summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-11-04 13:03:16 +0100
committerFlorian Dold <florian@dold.me>2022-11-04 13:03:16 +0100
commit62da8384e6239c2be34553c2e96ff31d49b9ea8f (patch)
treec6de228def505b20e2dd37cdc91a409448077bc8
parent8c711cc4f9672ec62ce905c8df8b8b4720a960be (diff)
downloadwallet-core-prebuilt.tar.gz
wallet-core-prebuilt.tar.bz2
wallet-core-prebuilt.zip
prebuilt v0.9.0prebuilt
-rw-r--r--v0.9.0/taler-wallet-embedded.js52786
1 files changed, 52786 insertions, 0 deletions
diff --git a/v0.9.0/taler-wallet-embedded.js b/v0.9.0/taler-wallet-embedded.js
new file mode 100644
index 000000000..3d0314306
--- /dev/null
+++ b/v0.9.0/taler-wallet-embedded.js
@@ -0,0 +1,52786 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var cr = require('crypto');
+var module$1 = require('module');
+var nodejs_path = require('path');
+var nodejs_os = require('os');
+var nodejs_fs = require('fs');
+var process$1 = require('process');
+var readline = require('readline');
+var require$$1$2 = require('http');
+var require$$2 = require('https');
+var require$$0$1 = require('url');
+var require$$3 = require('stream');
+var require$$4 = require('assert');
+var require$$1 = require('tty');
+var require$$1$1 = require('util');
+var require$$8 = require('zlib');
+var child_process = require('child_process');
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+function _interopNamespace(e) {
+ if (e && e.__esModule) return e;
+ var n = Object.create(null);
+ if (e) {
+ Object.keys(e).forEach(function (k) {
+ if (k !== 'default') {
+ var d = Object.getOwnPropertyDescriptor(e, k);
+ Object.defineProperty(n, k, d.get ? d : {
+ enumerable: true,
+ get: function () { return e[k]; }
+ });
+ }
+ });
+ }
+ n["default"] = e;
+ return Object.freeze(n);
+}
+
+var cr__default = /*#__PURE__*/_interopDefaultLegacy(cr);
+var nodejs_path__default = /*#__PURE__*/_interopDefaultLegacy(nodejs_path);
+var nodejs_os__default = /*#__PURE__*/_interopDefaultLegacy(nodejs_os);
+var nodejs_fs__default = /*#__PURE__*/_interopDefaultLegacy(nodejs_fs);
+var nodejs_fs__namespace = /*#__PURE__*/_interopNamespace(nodejs_fs);
+var process__default = /*#__PURE__*/_interopDefaultLegacy(process$1);
+var readline__default = /*#__PURE__*/_interopDefaultLegacy(readline);
+var require$$1__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$1$2);
+var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
+var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
+var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
+var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
+var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
+var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
+var require$$8__default = /*#__PURE__*/_interopDefaultLegacy(require$$8);
+var child_process__default = /*#__PURE__*/_interopDefaultLegacy(child_process);
+
+/******************************************************************************
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+***************************************************************************** */
+
+function __awaiter(thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+}
+
+// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
+// TypeScript port in 2019 by Florian Dold.
+// Public domain.
+//
+// Implementation derived from TweetNaCl version 20140427.
+// See for details: http://tweetnacl.cr.yp.to/
+const gf = function (init = []) {
+ const r = new Float64Array(16);
+ if (init)
+ for (let i = 0; i < init.length; i++)
+ r[i] = init[i];
+ return r;
+};
+// Pluggable, initialized in high-level API below.
+let randombytes = function (x, n) {
+ throw new Error("no PRNG");
+};
+const _9 = new Uint8Array(32);
+_9[0] = 9;
+// prettier-ignore
+const gf0 = gf();
+const gf1 = gf([1]);
+const _121665 = gf([0xdb41, 1]);
+const D = gf([
+ 0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898,
+ 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203,
+]);
+const D2 = gf([
+ 0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130,
+ 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406,
+]);
+const X = gf([
+ 0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c,
+ 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169,
+]);
+const Y = gf([
+ 0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
+ 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
+]);
+const I = gf([
+ 0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7,
+ 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83,
+]);
+function ts64(x, i, h, l) {
+ x[i] = (h >> 24) & 0xff;
+ x[i + 1] = (h >> 16) & 0xff;
+ x[i + 2] = (h >> 8) & 0xff;
+ x[i + 3] = h & 0xff;
+ x[i + 4] = (l >> 24) & 0xff;
+ x[i + 5] = (l >> 16) & 0xff;
+ x[i + 6] = (l >> 8) & 0xff;
+ x[i + 7] = l & 0xff;
+}
+function vn(x, xi, y, yi, n) {
+ let i, d = 0;
+ for (i = 0; i < n; i++)
+ d |= x[xi + i] ^ y[yi + i];
+ return (1 & ((d - 1) >>> 8)) - 1;
+}
+function crypto_verify_16(x, xi, y, yi) {
+ return vn(x, xi, y, yi, 16);
+}
+function crypto_verify_32(x, xi, y, yi) {
+ return vn(x, xi, y, yi, 32);
+}
+function core_salsa20(o, p, k, c) {
+ var j0 = (c[0] & 0xff) |
+ ((c[1] & 0xff) << 8) |
+ ((c[2] & 0xff) << 16) |
+ ((c[3] & 0xff) << 24), j1 = (k[0] & 0xff) |
+ ((k[1] & 0xff) << 8) |
+ ((k[2] & 0xff) << 16) |
+ ((k[3] & 0xff) << 24), j2 = (k[4] & 0xff) |
+ ((k[5] & 0xff) << 8) |
+ ((k[6] & 0xff) << 16) |
+ ((k[7] & 0xff) << 24), j3 = (k[8] & 0xff) |
+ ((k[9] & 0xff) << 8) |
+ ((k[10] & 0xff) << 16) |
+ ((k[11] & 0xff) << 24), j4 = (k[12] & 0xff) |
+ ((k[13] & 0xff) << 8) |
+ ((k[14] & 0xff) << 16) |
+ ((k[15] & 0xff) << 24), j5 = (c[4] & 0xff) |
+ ((c[5] & 0xff) << 8) |
+ ((c[6] & 0xff) << 16) |
+ ((c[7] & 0xff) << 24), j6 = (p[0] & 0xff) |
+ ((p[1] & 0xff) << 8) |
+ ((p[2] & 0xff) << 16) |
+ ((p[3] & 0xff) << 24), j7 = (p[4] & 0xff) |
+ ((p[5] & 0xff) << 8) |
+ ((p[6] & 0xff) << 16) |
+ ((p[7] & 0xff) << 24), j8 = (p[8] & 0xff) |
+ ((p[9] & 0xff) << 8) |
+ ((p[10] & 0xff) << 16) |
+ ((p[11] & 0xff) << 24), j9 = (p[12] & 0xff) |
+ ((p[13] & 0xff) << 8) |
+ ((p[14] & 0xff) << 16) |
+ ((p[15] & 0xff) << 24), j10 = (c[8] & 0xff) |
+ ((c[9] & 0xff) << 8) |
+ ((c[10] & 0xff) << 16) |
+ ((c[11] & 0xff) << 24), j11 = (k[16] & 0xff) |
+ ((k[17] & 0xff) << 8) |
+ ((k[18] & 0xff) << 16) |
+ ((k[19] & 0xff) << 24), j12 = (k[20] & 0xff) |
+ ((k[21] & 0xff) << 8) |
+ ((k[22] & 0xff) << 16) |
+ ((k[23] & 0xff) << 24), j13 = (k[24] & 0xff) |
+ ((k[25] & 0xff) << 8) |
+ ((k[26] & 0xff) << 16) |
+ ((k[27] & 0xff) << 24), j14 = (k[28] & 0xff) |
+ ((k[29] & 0xff) << 8) |
+ ((k[30] & 0xff) << 16) |
+ ((k[31] & 0xff) << 24), j15 = (c[12] & 0xff) |
+ ((c[13] & 0xff) << 8) |
+ ((c[14] & 0xff) << 16) |
+ ((c[15] & 0xff) << 24);
+ var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
+ for (var i = 0; i < 20; i += 2) {
+ u = (x0 + x12) | 0;
+ x4 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x4 + x0) | 0;
+ x8 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x8 + x4) | 0;
+ x12 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x12 + x8) | 0;
+ x0 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x5 + x1) | 0;
+ x9 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x9 + x5) | 0;
+ x13 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x13 + x9) | 0;
+ x1 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x1 + x13) | 0;
+ x5 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x10 + x6) | 0;
+ x14 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x14 + x10) | 0;
+ x2 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x2 + x14) | 0;
+ x6 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x6 + x2) | 0;
+ x10 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x15 + x11) | 0;
+ x3 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x3 + x15) | 0;
+ x7 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x7 + x3) | 0;
+ x11 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x11 + x7) | 0;
+ x15 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x0 + x3) | 0;
+ x1 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x1 + x0) | 0;
+ x2 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x2 + x1) | 0;
+ x3 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x3 + x2) | 0;
+ x0 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x5 + x4) | 0;
+ x6 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x6 + x5) | 0;
+ x7 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x7 + x6) | 0;
+ x4 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x4 + x7) | 0;
+ x5 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x10 + x9) | 0;
+ x11 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x11 + x10) | 0;
+ x8 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x8 + x11) | 0;
+ x9 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x9 + x8) | 0;
+ x10 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x15 + x14) | 0;
+ x12 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x12 + x15) | 0;
+ x13 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x13 + x12) | 0;
+ x14 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x14 + x13) | 0;
+ x15 ^= (u << 18) | (u >>> (32 - 18));
+ }
+ x0 = (x0 + j0) | 0;
+ x1 = (x1 + j1) | 0;
+ x2 = (x2 + j2) | 0;
+ x3 = (x3 + j3) | 0;
+ x4 = (x4 + j4) | 0;
+ x5 = (x5 + j5) | 0;
+ x6 = (x6 + j6) | 0;
+ x7 = (x7 + j7) | 0;
+ x8 = (x8 + j8) | 0;
+ x9 = (x9 + j9) | 0;
+ x10 = (x10 + j10) | 0;
+ x11 = (x11 + j11) | 0;
+ x12 = (x12 + j12) | 0;
+ x13 = (x13 + j13) | 0;
+ x14 = (x14 + j14) | 0;
+ x15 = (x15 + j15) | 0;
+ o[0] = (x0 >>> 0) & 0xff;
+ o[1] = (x0 >>> 8) & 0xff;
+ o[2] = (x0 >>> 16) & 0xff;
+ o[3] = (x0 >>> 24) & 0xff;
+ o[4] = (x1 >>> 0) & 0xff;
+ o[5] = (x1 >>> 8) & 0xff;
+ o[6] = (x1 >>> 16) & 0xff;
+ o[7] = (x1 >>> 24) & 0xff;
+ o[8] = (x2 >>> 0) & 0xff;
+ o[9] = (x2 >>> 8) & 0xff;
+ o[10] = (x2 >>> 16) & 0xff;
+ o[11] = (x2 >>> 24) & 0xff;
+ o[12] = (x3 >>> 0) & 0xff;
+ o[13] = (x3 >>> 8) & 0xff;
+ o[14] = (x3 >>> 16) & 0xff;
+ o[15] = (x3 >>> 24) & 0xff;
+ o[16] = (x4 >>> 0) & 0xff;
+ o[17] = (x4 >>> 8) & 0xff;
+ o[18] = (x4 >>> 16) & 0xff;
+ o[19] = (x4 >>> 24) & 0xff;
+ o[20] = (x5 >>> 0) & 0xff;
+ o[21] = (x5 >>> 8) & 0xff;
+ o[22] = (x5 >>> 16) & 0xff;
+ o[23] = (x5 >>> 24) & 0xff;
+ o[24] = (x6 >>> 0) & 0xff;
+ o[25] = (x6 >>> 8) & 0xff;
+ o[26] = (x6 >>> 16) & 0xff;
+ o[27] = (x6 >>> 24) & 0xff;
+ o[28] = (x7 >>> 0) & 0xff;
+ o[29] = (x7 >>> 8) & 0xff;
+ o[30] = (x7 >>> 16) & 0xff;
+ o[31] = (x7 >>> 24) & 0xff;
+ o[32] = (x8 >>> 0) & 0xff;
+ o[33] = (x8 >>> 8) & 0xff;
+ o[34] = (x8 >>> 16) & 0xff;
+ o[35] = (x8 >>> 24) & 0xff;
+ o[36] = (x9 >>> 0) & 0xff;
+ o[37] = (x9 >>> 8) & 0xff;
+ o[38] = (x9 >>> 16) & 0xff;
+ o[39] = (x9 >>> 24) & 0xff;
+ o[40] = (x10 >>> 0) & 0xff;
+ o[41] = (x10 >>> 8) & 0xff;
+ o[42] = (x10 >>> 16) & 0xff;
+ o[43] = (x10 >>> 24) & 0xff;
+ o[44] = (x11 >>> 0) & 0xff;
+ o[45] = (x11 >>> 8) & 0xff;
+ o[46] = (x11 >>> 16) & 0xff;
+ o[47] = (x11 >>> 24) & 0xff;
+ o[48] = (x12 >>> 0) & 0xff;
+ o[49] = (x12 >>> 8) & 0xff;
+ o[50] = (x12 >>> 16) & 0xff;
+ o[51] = (x12 >>> 24) & 0xff;
+ o[52] = (x13 >>> 0) & 0xff;
+ o[53] = (x13 >>> 8) & 0xff;
+ o[54] = (x13 >>> 16) & 0xff;
+ o[55] = (x13 >>> 24) & 0xff;
+ o[56] = (x14 >>> 0) & 0xff;
+ o[57] = (x14 >>> 8) & 0xff;
+ o[58] = (x14 >>> 16) & 0xff;
+ o[59] = (x14 >>> 24) & 0xff;
+ o[60] = (x15 >>> 0) & 0xff;
+ o[61] = (x15 >>> 8) & 0xff;
+ o[62] = (x15 >>> 16) & 0xff;
+ o[63] = (x15 >>> 24) & 0xff;
+}
+function core_hsalsa20(o, p, k, c) {
+ var j0 = (c[0] & 0xff) |
+ ((c[1] & 0xff) << 8) |
+ ((c[2] & 0xff) << 16) |
+ ((c[3] & 0xff) << 24), j1 = (k[0] & 0xff) |
+ ((k[1] & 0xff) << 8) |
+ ((k[2] & 0xff) << 16) |
+ ((k[3] & 0xff) << 24), j2 = (k[4] & 0xff) |
+ ((k[5] & 0xff) << 8) |
+ ((k[6] & 0xff) << 16) |
+ ((k[7] & 0xff) << 24), j3 = (k[8] & 0xff) |
+ ((k[9] & 0xff) << 8) |
+ ((k[10] & 0xff) << 16) |
+ ((k[11] & 0xff) << 24), j4 = (k[12] & 0xff) |
+ ((k[13] & 0xff) << 8) |
+ ((k[14] & 0xff) << 16) |
+ ((k[15] & 0xff) << 24), j5 = (c[4] & 0xff) |
+ ((c[5] & 0xff) << 8) |
+ ((c[6] & 0xff) << 16) |
+ ((c[7] & 0xff) << 24), j6 = (p[0] & 0xff) |
+ ((p[1] & 0xff) << 8) |
+ ((p[2] & 0xff) << 16) |
+ ((p[3] & 0xff) << 24), j7 = (p[4] & 0xff) |
+ ((p[5] & 0xff) << 8) |
+ ((p[6] & 0xff) << 16) |
+ ((p[7] & 0xff) << 24), j8 = (p[8] & 0xff) |
+ ((p[9] & 0xff) << 8) |
+ ((p[10] & 0xff) << 16) |
+ ((p[11] & 0xff) << 24), j9 = (p[12] & 0xff) |
+ ((p[13] & 0xff) << 8) |
+ ((p[14] & 0xff) << 16) |
+ ((p[15] & 0xff) << 24), j10 = (c[8] & 0xff) |
+ ((c[9] & 0xff) << 8) |
+ ((c[10] & 0xff) << 16) |
+ ((c[11] & 0xff) << 24), j11 = (k[16] & 0xff) |
+ ((k[17] & 0xff) << 8) |
+ ((k[18] & 0xff) << 16) |
+ ((k[19] & 0xff) << 24), j12 = (k[20] & 0xff) |
+ ((k[21] & 0xff) << 8) |
+ ((k[22] & 0xff) << 16) |
+ ((k[23] & 0xff) << 24), j13 = (k[24] & 0xff) |
+ ((k[25] & 0xff) << 8) |
+ ((k[26] & 0xff) << 16) |
+ ((k[27] & 0xff) << 24), j14 = (k[28] & 0xff) |
+ ((k[29] & 0xff) << 8) |
+ ((k[30] & 0xff) << 16) |
+ ((k[31] & 0xff) << 24), j15 = (c[12] & 0xff) |
+ ((c[13] & 0xff) << 8) |
+ ((c[14] & 0xff) << 16) |
+ ((c[15] & 0xff) << 24);
+ var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
+ for (var i = 0; i < 20; i += 2) {
+ u = (x0 + x12) | 0;
+ x4 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x4 + x0) | 0;
+ x8 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x8 + x4) | 0;
+ x12 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x12 + x8) | 0;
+ x0 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x5 + x1) | 0;
+ x9 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x9 + x5) | 0;
+ x13 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x13 + x9) | 0;
+ x1 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x1 + x13) | 0;
+ x5 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x10 + x6) | 0;
+ x14 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x14 + x10) | 0;
+ x2 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x2 + x14) | 0;
+ x6 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x6 + x2) | 0;
+ x10 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x15 + x11) | 0;
+ x3 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x3 + x15) | 0;
+ x7 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x7 + x3) | 0;
+ x11 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x11 + x7) | 0;
+ x15 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x0 + x3) | 0;
+ x1 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x1 + x0) | 0;
+ x2 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x2 + x1) | 0;
+ x3 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x3 + x2) | 0;
+ x0 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x5 + x4) | 0;
+ x6 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x6 + x5) | 0;
+ x7 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x7 + x6) | 0;
+ x4 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x4 + x7) | 0;
+ x5 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x10 + x9) | 0;
+ x11 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x11 + x10) | 0;
+ x8 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x8 + x11) | 0;
+ x9 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x9 + x8) | 0;
+ x10 ^= (u << 18) | (u >>> (32 - 18));
+ u = (x15 + x14) | 0;
+ x12 ^= (u << 7) | (u >>> (32 - 7));
+ u = (x12 + x15) | 0;
+ x13 ^= (u << 9) | (u >>> (32 - 9));
+ u = (x13 + x12) | 0;
+ x14 ^= (u << 13) | (u >>> (32 - 13));
+ u = (x14 + x13) | 0;
+ x15 ^= (u << 18) | (u >>> (32 - 18));
+ }
+ o[0] = (x0 >>> 0) & 0xff;
+ o[1] = (x0 >>> 8) & 0xff;
+ o[2] = (x0 >>> 16) & 0xff;
+ o[3] = (x0 >>> 24) & 0xff;
+ o[4] = (x5 >>> 0) & 0xff;
+ o[5] = (x5 >>> 8) & 0xff;
+ o[6] = (x5 >>> 16) & 0xff;
+ o[7] = (x5 >>> 24) & 0xff;
+ o[8] = (x10 >>> 0) & 0xff;
+ o[9] = (x10 >>> 8) & 0xff;
+ o[10] = (x10 >>> 16) & 0xff;
+ o[11] = (x10 >>> 24) & 0xff;
+ o[12] = (x15 >>> 0) & 0xff;
+ o[13] = (x15 >>> 8) & 0xff;
+ o[14] = (x15 >>> 16) & 0xff;
+ o[15] = (x15 >>> 24) & 0xff;
+ o[16] = (x6 >>> 0) & 0xff;
+ o[17] = (x6 >>> 8) & 0xff;
+ o[18] = (x6 >>> 16) & 0xff;
+ o[19] = (x6 >>> 24) & 0xff;
+ o[20] = (x7 >>> 0) & 0xff;
+ o[21] = (x7 >>> 8) & 0xff;
+ o[22] = (x7 >>> 16) & 0xff;
+ o[23] = (x7 >>> 24) & 0xff;
+ o[24] = (x8 >>> 0) & 0xff;
+ o[25] = (x8 >>> 8) & 0xff;
+ o[26] = (x8 >>> 16) & 0xff;
+ o[27] = (x8 >>> 24) & 0xff;
+ o[28] = (x9 >>> 0) & 0xff;
+ o[29] = (x9 >>> 8) & 0xff;
+ o[30] = (x9 >>> 16) & 0xff;
+ o[31] = (x9 >>> 24) & 0xff;
+}
+var sigma = new Uint8Array([
+ 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107,
+]);
+// "expand 32-byte k"
+function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
+ var z = new Uint8Array(16), x = new Uint8Array(64);
+ var u, i;
+ for (i = 0; i < 16; i++)
+ z[i] = 0;
+ for (i = 0; i < 8; i++)
+ z[i] = n[i];
+ while (b >= 64) {
+ core_salsa20(x, z, k, sigma);
+ for (i = 0; i < 64; i++)
+ c[cpos + i] = m[mpos + i] ^ x[i];
+ u = 1;
+ for (i = 8; i < 16; i++) {
+ u = (u + (z[i] & 0xff)) | 0;
+ z[i] = u & 0xff;
+ u >>>= 8;
+ }
+ b -= 64;
+ cpos += 64;
+ mpos += 64;
+ }
+ if (b > 0) {
+ core_salsa20(x, z, k, sigma);
+ for (i = 0; i < b; i++)
+ c[cpos + i] = m[mpos + i] ^ x[i];
+ }
+ return 0;
+}
+function crypto_stream_salsa20(c, cpos, b, n, k) {
+ var z = new Uint8Array(16), x = new Uint8Array(64);
+ var u, i;
+ for (i = 0; i < 16; i++)
+ z[i] = 0;
+ for (i = 0; i < 8; i++)
+ z[i] = n[i];
+ while (b >= 64) {
+ core_salsa20(x, z, k, sigma);
+ for (i = 0; i < 64; i++)
+ c[cpos + i] = x[i];
+ u = 1;
+ for (i = 8; i < 16; i++) {
+ u = (u + (z[i] & 0xff)) | 0;
+ z[i] = u & 0xff;
+ u >>>= 8;
+ }
+ b -= 64;
+ cpos += 64;
+ }
+ if (b > 0) {
+ core_salsa20(x, z, k, sigma);
+ for (i = 0; i < b; i++)
+ c[cpos + i] = x[i];
+ }
+ return 0;
+}
+function crypto_stream(c, cpos, d, n, k) {
+ var s = new Uint8Array(32);
+ core_hsalsa20(s, n, k, sigma);
+ var sn = new Uint8Array(8);
+ for (var i = 0; i < 8; i++)
+ sn[i] = n[i + 16];
+ return crypto_stream_salsa20(c, cpos, d, sn, s);
+}
+function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
+ var s = new Uint8Array(32);
+ core_hsalsa20(s, n, k, sigma);
+ var sn = new Uint8Array(8);
+ for (var i = 0; i < 8; i++)
+ sn[i] = n[i + 16];
+ return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s);
+}
+/*
+ * Port of Andrew Moon's Poly1305-donna-16. Public domain.
+ * https://github.com/floodyberry/poly1305-donna
+ */
+class poly1305 {
+ constructor(key) {
+ this.buffer = new Uint8Array(16);
+ this.r = new Uint16Array(10);
+ this.h = new Uint16Array(10);
+ this.pad = new Uint16Array(8);
+ this.leftover = 0;
+ this.fin = 0;
+ var t0, t1, t2, t3, t4, t5, t6, t7;
+ t0 = (key[0] & 0xff) | ((key[1] & 0xff) << 8);
+ this.r[0] = t0 & 0x1fff;
+ t1 = (key[2] & 0xff) | ((key[3] & 0xff) << 8);
+ this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
+ t2 = (key[4] & 0xff) | ((key[5] & 0xff) << 8);
+ this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
+ t3 = (key[6] & 0xff) | ((key[7] & 0xff) << 8);
+ this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
+ t4 = (key[8] & 0xff) | ((key[9] & 0xff) << 8);
+ this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
+ this.r[5] = (t4 >>> 1) & 0x1ffe;
+ t5 = (key[10] & 0xff) | ((key[11] & 0xff) << 8);
+ this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
+ t6 = (key[12] & 0xff) | ((key[13] & 0xff) << 8);
+ this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
+ t7 = (key[14] & 0xff) | ((key[15] & 0xff) << 8);
+ this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
+ this.r[9] = (t7 >>> 5) & 0x007f;
+ this.pad[0] = (key[16] & 0xff) | ((key[17] & 0xff) << 8);
+ this.pad[1] = (key[18] & 0xff) | ((key[19] & 0xff) << 8);
+ this.pad[2] = (key[20] & 0xff) | ((key[21] & 0xff) << 8);
+ this.pad[3] = (key[22] & 0xff) | ((key[23] & 0xff) << 8);
+ this.pad[4] = (key[24] & 0xff) | ((key[25] & 0xff) << 8);
+ this.pad[5] = (key[26] & 0xff) | ((key[27] & 0xff) << 8);
+ this.pad[6] = (key[28] & 0xff) | ((key[29] & 0xff) << 8);
+ this.pad[7] = (key[30] & 0xff) | ((key[31] & 0xff) << 8);
+ }
+ blocks(m, mpos, bytes) {
+ var hibit = this.fin ? 0 : 1 << 11;
+ var t0, t1, t2, t3, t4, t5, t6, t7, c;
+ var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
+ var h0 = this.h[0], h1 = this.h[1], h2 = this.h[2], h3 = this.h[3], h4 = this.h[4], h5 = this.h[5], h6 = this.h[6], h7 = this.h[7], h8 = this.h[8], h9 = this.h[9];
+ var r0 = this.r[0], r1 = this.r[1], r2 = this.r[2], r3 = this.r[3], r4 = this.r[4], r5 = this.r[5], r6 = this.r[6], r7 = this.r[7], r8 = this.r[8], r9 = this.r[9];
+ while (bytes >= 16) {
+ t0 = (m[mpos + 0] & 0xff) | ((m[mpos + 1] & 0xff) << 8);
+ h0 += t0 & 0x1fff;
+ t1 = (m[mpos + 2] & 0xff) | ((m[mpos + 3] & 0xff) << 8);
+ h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
+ t2 = (m[mpos + 4] & 0xff) | ((m[mpos + 5] & 0xff) << 8);
+ h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
+ t3 = (m[mpos + 6] & 0xff) | ((m[mpos + 7] & 0xff) << 8);
+ h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
+ t4 = (m[mpos + 8] & 0xff) | ((m[mpos + 9] & 0xff) << 8);
+ h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
+ h5 += (t4 >>> 1) & 0x1fff;
+ t5 = (m[mpos + 10] & 0xff) | ((m[mpos + 11] & 0xff) << 8);
+ h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
+ t6 = (m[mpos + 12] & 0xff) | ((m[mpos + 13] & 0xff) << 8);
+ h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
+ t7 = (m[mpos + 14] & 0xff) | ((m[mpos + 15] & 0xff) << 8);
+ h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
+ h9 += (t7 >>> 5) | hibit;
+ c = 0;
+ d0 = c;
+ d0 += h0 * r0;
+ d0 += h1 * (5 * r9);
+ d0 += h2 * (5 * r8);
+ d0 += h3 * (5 * r7);
+ d0 += h4 * (5 * r6);
+ c = d0 >>> 13;
+ d0 &= 0x1fff;
+ d0 += h5 * (5 * r5);
+ d0 += h6 * (5 * r4);
+ d0 += h7 * (5 * r3);
+ d0 += h8 * (5 * r2);
+ d0 += h9 * (5 * r1);
+ c += d0 >>> 13;
+ d0 &= 0x1fff;
+ d1 = c;
+ d1 += h0 * r1;
+ d1 += h1 * r0;
+ d1 += h2 * (5 * r9);
+ d1 += h3 * (5 * r8);
+ d1 += h4 * (5 * r7);
+ c = d1 >>> 13;
+ d1 &= 0x1fff;
+ d1 += h5 * (5 * r6);
+ d1 += h6 * (5 * r5);
+ d1 += h7 * (5 * r4);
+ d1 += h8 * (5 * r3);
+ d1 += h9 * (5 * r2);
+ c += d1 >>> 13;
+ d1 &= 0x1fff;
+ d2 = c;
+ d2 += h0 * r2;
+ d2 += h1 * r1;
+ d2 += h2 * r0;
+ d2 += h3 * (5 * r9);
+ d2 += h4 * (5 * r8);
+ c = d2 >>> 13;
+ d2 &= 0x1fff;
+ d2 += h5 * (5 * r7);
+ d2 += h6 * (5 * r6);
+ d2 += h7 * (5 * r5);
+ d2 += h8 * (5 * r4);
+ d2 += h9 * (5 * r3);
+ c += d2 >>> 13;
+ d2 &= 0x1fff;
+ d3 = c;
+ d3 += h0 * r3;
+ d3 += h1 * r2;
+ d3 += h2 * r1;
+ d3 += h3 * r0;
+ d3 += h4 * (5 * r9);
+ c = d3 >>> 13;
+ d3 &= 0x1fff;
+ d3 += h5 * (5 * r8);
+ d3 += h6 * (5 * r7);
+ d3 += h7 * (5 * r6);
+ d3 += h8 * (5 * r5);
+ d3 += h9 * (5 * r4);
+ c += d3 >>> 13;
+ d3 &= 0x1fff;
+ d4 = c;
+ d4 += h0 * r4;
+ d4 += h1 * r3;
+ d4 += h2 * r2;
+ d4 += h3 * r1;
+ d4 += h4 * r0;
+ c = d4 >>> 13;
+ d4 &= 0x1fff;
+ d4 += h5 * (5 * r9);
+ d4 += h6 * (5 * r8);
+ d4 += h7 * (5 * r7);
+ d4 += h8 * (5 * r6);
+ d4 += h9 * (5 * r5);
+ c += d4 >>> 13;
+ d4 &= 0x1fff;
+ d5 = c;
+ d5 += h0 * r5;
+ d5 += h1 * r4;
+ d5 += h2 * r3;
+ d5 += h3 * r2;
+ d5 += h4 * r1;
+ c = d5 >>> 13;
+ d5 &= 0x1fff;
+ d5 += h5 * r0;
+ d5 += h6 * (5 * r9);
+ d5 += h7 * (5 * r8);
+ d5 += h8 * (5 * r7);
+ d5 += h9 * (5 * r6);
+ c += d5 >>> 13;
+ d5 &= 0x1fff;
+ d6 = c;
+ d6 += h0 * r6;
+ d6 += h1 * r5;
+ d6 += h2 * r4;
+ d6 += h3 * r3;
+ d6 += h4 * r2;
+ c = d6 >>> 13;
+ d6 &= 0x1fff;
+ d6 += h5 * r1;
+ d6 += h6 * r0;
+ d6 += h7 * (5 * r9);
+ d6 += h8 * (5 * r8);
+ d6 += h9 * (5 * r7);
+ c += d6 >>> 13;
+ d6 &= 0x1fff;
+ d7 = c;
+ d7 += h0 * r7;
+ d7 += h1 * r6;
+ d7 += h2 * r5;
+ d7 += h3 * r4;
+ d7 += h4 * r3;
+ c = d7 >>> 13;
+ d7 &= 0x1fff;
+ d7 += h5 * r2;
+ d7 += h6 * r1;
+ d7 += h7 * r0;
+ d7 += h8 * (5 * r9);
+ d7 += h9 * (5 * r8);
+ c += d7 >>> 13;
+ d7 &= 0x1fff;
+ d8 = c;
+ d8 += h0 * r8;
+ d8 += h1 * r7;
+ d8 += h2 * r6;
+ d8 += h3 * r5;
+ d8 += h4 * r4;
+ c = d8 >>> 13;
+ d8 &= 0x1fff;
+ d8 += h5 * r3;
+ d8 += h6 * r2;
+ d8 += h7 * r1;
+ d8 += h8 * r0;
+ d8 += h9 * (5 * r9);
+ c += d8 >>> 13;
+ d8 &= 0x1fff;
+ d9 = c;
+ d9 += h0 * r9;
+ d9 += h1 * r8;
+ d9 += h2 * r7;
+ d9 += h3 * r6;
+ d9 += h4 * r5;
+ c = d9 >>> 13;
+ d9 &= 0x1fff;
+ d9 += h5 * r4;
+ d9 += h6 * r3;
+ d9 += h7 * r2;
+ d9 += h8 * r1;
+ d9 += h9 * r0;
+ c += d9 >>> 13;
+ d9 &= 0x1fff;
+ c = ((c << 2) + c) | 0;
+ c = (c + d0) | 0;
+ d0 = c & 0x1fff;
+ c = c >>> 13;
+ d1 += c;
+ h0 = d0;
+ h1 = d1;
+ h2 = d2;
+ h3 = d3;
+ h4 = d4;
+ h5 = d5;
+ h6 = d6;
+ h7 = d7;
+ h8 = d8;
+ h9 = d9;
+ mpos += 16;
+ bytes -= 16;
+ }
+ this.h[0] = h0;
+ this.h[1] = h1;
+ this.h[2] = h2;
+ this.h[3] = h3;
+ this.h[4] = h4;
+ this.h[5] = h5;
+ this.h[6] = h6;
+ this.h[7] = h7;
+ this.h[8] = h8;
+ this.h[9] = h9;
+ }
+ finish(mac, macpos) {
+ var g = new Uint16Array(10);
+ var c, mask, f, i;
+ if (this.leftover) {
+ i = this.leftover;
+ this.buffer[i++] = 1;
+ for (; i < 16; i++)
+ this.buffer[i] = 0;
+ this.fin = 1;
+ this.blocks(this.buffer, 0, 16);
+ }
+ c = this.h[1] >>> 13;
+ this.h[1] &= 0x1fff;
+ for (i = 2; i < 10; i++) {
+ this.h[i] += c;
+ c = this.h[i] >>> 13;
+ this.h[i] &= 0x1fff;
+ }
+ this.h[0] += c * 5;
+ c = this.h[0] >>> 13;
+ this.h[0] &= 0x1fff;
+ this.h[1] += c;
+ c = this.h[1] >>> 13;
+ this.h[1] &= 0x1fff;
+ this.h[2] += c;
+ g[0] = this.h[0] + 5;
+ c = g[0] >>> 13;
+ g[0] &= 0x1fff;
+ for (i = 1; i < 10; i++) {
+ g[i] = this.h[i] + c;
+ c = g[i] >>> 13;
+ g[i] &= 0x1fff;
+ }
+ g[9] -= 1 << 13;
+ mask = (c ^ 1) - 1;
+ for (i = 0; i < 10; i++)
+ g[i] &= mask;
+ mask = ~mask;
+ for (i = 0; i < 10; i++)
+ this.h[i] = (this.h[i] & mask) | g[i];
+ this.h[0] = (this.h[0] | (this.h[1] << 13)) & 0xffff;
+ this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff;
+ this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff;
+ this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff;
+ this.h[4] =
+ ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
+ this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff;
+ this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff;
+ this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff;
+ f = this.h[0] + this.pad[0];
+ this.h[0] = f & 0xffff;
+ for (i = 1; i < 8; i++) {
+ f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
+ this.h[i] = f & 0xffff;
+ }
+ mac[macpos + 0] = (this.h[0] >>> 0) & 0xff;
+ mac[macpos + 1] = (this.h[0] >>> 8) & 0xff;
+ mac[macpos + 2] = (this.h[1] >>> 0) & 0xff;
+ mac[macpos + 3] = (this.h[1] >>> 8) & 0xff;
+ mac[macpos + 4] = (this.h[2] >>> 0) & 0xff;
+ mac[macpos + 5] = (this.h[2] >>> 8) & 0xff;
+ mac[macpos + 6] = (this.h[3] >>> 0) & 0xff;
+ mac[macpos + 7] = (this.h[3] >>> 8) & 0xff;
+ mac[macpos + 8] = (this.h[4] >>> 0) & 0xff;
+ mac[macpos + 9] = (this.h[4] >>> 8) & 0xff;
+ mac[macpos + 10] = (this.h[5] >>> 0) & 0xff;
+ mac[macpos + 11] = (this.h[5] >>> 8) & 0xff;
+ mac[macpos + 12] = (this.h[6] >>> 0) & 0xff;
+ mac[macpos + 13] = (this.h[6] >>> 8) & 0xff;
+ mac[macpos + 14] = (this.h[7] >>> 0) & 0xff;
+ mac[macpos + 15] = (this.h[7] >>> 8) & 0xff;
+ }
+ update(m, mpos, bytes) {
+ let i;
+ let want;
+ if (this.leftover) {
+ want = 16 - this.leftover;
+ if (want > bytes)
+ want = bytes;
+ for (i = 0; i < want; i++)
+ this.buffer[this.leftover + i] = m[mpos + i];
+ bytes -= want;
+ mpos += want;
+ this.leftover += want;
+ if (this.leftover < 16)
+ return;
+ this.blocks(this.buffer, 0, 16);
+ this.leftover = 0;
+ }
+ if (bytes >= 16) {
+ want = bytes - (bytes % 16);
+ this.blocks(m, mpos, want);
+ mpos += want;
+ bytes -= want;
+ }
+ if (bytes) {
+ for (i = 0; i < bytes; i++)
+ this.buffer[this.leftover + i] = m[mpos + i];
+ this.leftover += bytes;
+ }
+ }
+}
+function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
+ var s = new poly1305(k);
+ s.update(m, mpos, n);
+ s.finish(out, outpos);
+ return 0;
+}
+function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
+ var x = new Uint8Array(16);
+ crypto_onetimeauth(x, 0, m, mpos, n, k);
+ return crypto_verify_16(h, hpos, x, 0);
+}
+function crypto_secretbox(c, m, d, n, k) {
+ var i;
+ if (d < 32)
+ return -1;
+ crypto_stream_xor(c, 0, m, 0, d, n, k);
+ crypto_onetimeauth(c, 16, c, 32, d - 32, c);
+ for (i = 0; i < 16; i++)
+ c[i] = 0;
+ return 0;
+}
+function crypto_secretbox_open(m, c, d, n, k) {
+ var i;
+ var x = new Uint8Array(32);
+ if (d < 32)
+ return -1;
+ crypto_stream(x, 0, 32, n, k);
+ if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0)
+ return -1;
+ crypto_stream_xor(m, 0, c, 0, d, n, k);
+ for (i = 0; i < 32; i++)
+ m[i] = 0;
+ return 0;
+}
+function set25519(r, a) {
+ let i;
+ for (i = 0; i < 16; i++)
+ r[i] = a[i] | 0;
+}
+function car25519(o) {
+ let i, v, c = 1;
+ for (i = 0; i < 16; i++) {
+ v = o[i] + c + 65535;
+ c = Math.floor(v / 65536);
+ o[i] = v - c * 65536;
+ }
+ o[0] += c - 1 + 37 * (c - 1);
+}
+function sel25519(p, q, b) {
+ let t;
+ const c = ~(b - 1);
+ for (let i = 0; i < 16; i++) {
+ t = c & (p[i] ^ q[i]);
+ p[i] ^= t;
+ q[i] ^= t;
+ }
+}
+function pack25519(o, n) {
+ let i, j, b;
+ const m = gf(), t = gf();
+ for (i = 0; i < 16; i++)
+ t[i] = n[i];
+ car25519(t);
+ car25519(t);
+ car25519(t);
+ for (j = 0; j < 2; j++) {
+ m[0] = t[0] - 0xffed;
+ for (i = 1; i < 15; i++) {
+ m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
+ m[i - 1] &= 0xffff;
+ }
+ m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
+ b = (m[15] >> 16) & 1;
+ m[14] &= 0xffff;
+ sel25519(t, m, 1 - b);
+ }
+ for (i = 0; i < 16; i++) {
+ o[2 * i] = t[i] & 0xff;
+ o[2 * i + 1] = t[i] >> 8;
+ }
+}
+function neq25519(a, b) {
+ const c = new Uint8Array(32), d = new Uint8Array(32);
+ pack25519(c, a);
+ pack25519(d, b);
+ return crypto_verify_32(c, 0, d, 0);
+}
+function par25519(a) {
+ const d = new Uint8Array(32);
+ pack25519(d, a);
+ return d[0] & 1;
+}
+function unpack25519(o, n) {
+ let i;
+ for (i = 0; i < 16; i++)
+ o[i] = n[2 * i] + (n[2 * i + 1] << 8);
+ o[15] &= 0x7fff;
+}
+function A(o, a, b) {
+ for (let i = 0; i < 16; i++)
+ o[i] = a[i] + b[i];
+}
+function Z(o, a, b) {
+ for (let i = 0; i < 16; i++)
+ o[i] = a[i] - b[i];
+}
+function M(o, a, b) {
+ let v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0;
+ const b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
+ v = a[0];
+ t0 += v * b0;
+ t1 += v * b1;
+ t2 += v * b2;
+ t3 += v * b3;
+ t4 += v * b4;
+ t5 += v * b5;
+ t6 += v * b6;
+ t7 += v * b7;
+ t8 += v * b8;
+ t9 += v * b9;
+ t10 += v * b10;
+ t11 += v * b11;
+ t12 += v * b12;
+ t13 += v * b13;
+ t14 += v * b14;
+ t15 += v * b15;
+ v = a[1];
+ t1 += v * b0;
+ t2 += v * b1;
+ t3 += v * b2;
+ t4 += v * b3;
+ t5 += v * b4;
+ t6 += v * b5;
+ t7 += v * b6;
+ t8 += v * b7;
+ t9 += v * b8;
+ t10 += v * b9;
+ t11 += v * b10;
+ t12 += v * b11;
+ t13 += v * b12;
+ t14 += v * b13;
+ t15 += v * b14;
+ t16 += v * b15;
+ v = a[2];
+ t2 += v * b0;
+ t3 += v * b1;
+ t4 += v * b2;
+ t5 += v * b3;
+ t6 += v * b4;
+ t7 += v * b5;
+ t8 += v * b6;
+ t9 += v * b7;
+ t10 += v * b8;
+ t11 += v * b9;
+ t12 += v * b10;
+ t13 += v * b11;
+ t14 += v * b12;
+ t15 += v * b13;
+ t16 += v * b14;
+ t17 += v * b15;
+ v = a[3];
+ t3 += v * b0;
+ t4 += v * b1;
+ t5 += v * b2;
+ t6 += v * b3;
+ t7 += v * b4;
+ t8 += v * b5;
+ t9 += v * b6;
+ t10 += v * b7;
+ t11 += v * b8;
+ t12 += v * b9;
+ t13 += v * b10;
+ t14 += v * b11;
+ t15 += v * b12;
+ t16 += v * b13;
+ t17 += v * b14;
+ t18 += v * b15;
+ v = a[4];
+ t4 += v * b0;
+ t5 += v * b1;
+ t6 += v * b2;
+ t7 += v * b3;
+ t8 += v * b4;
+ t9 += v * b5;
+ t10 += v * b6;
+ t11 += v * b7;
+ t12 += v * b8;
+ t13 += v * b9;
+ t14 += v * b10;
+ t15 += v * b11;
+ t16 += v * b12;
+ t17 += v * b13;
+ t18 += v * b14;
+ t19 += v * b15;
+ v = a[5];
+ t5 += v * b0;
+ t6 += v * b1;
+ t7 += v * b2;
+ t8 += v * b3;
+ t9 += v * b4;
+ t10 += v * b5;
+ t11 += v * b6;
+ t12 += v * b7;
+ t13 += v * b8;
+ t14 += v * b9;
+ t15 += v * b10;
+ t16 += v * b11;
+ t17 += v * b12;
+ t18 += v * b13;
+ t19 += v * b14;
+ t20 += v * b15;
+ v = a[6];
+ t6 += v * b0;
+ t7 += v * b1;
+ t8 += v * b2;
+ t9 += v * b3;
+ t10 += v * b4;
+ t11 += v * b5;
+ t12 += v * b6;
+ t13 += v * b7;
+ t14 += v * b8;
+ t15 += v * b9;
+ t16 += v * b10;
+ t17 += v * b11;
+ t18 += v * b12;
+ t19 += v * b13;
+ t20 += v * b14;
+ t21 += v * b15;
+ v = a[7];
+ t7 += v * b0;
+ t8 += v * b1;
+ t9 += v * b2;
+ t10 += v * b3;
+ t11 += v * b4;
+ t12 += v * b5;
+ t13 += v * b6;
+ t14 += v * b7;
+ t15 += v * b8;
+ t16 += v * b9;
+ t17 += v * b10;
+ t18 += v * b11;
+ t19 += v * b12;
+ t20 += v * b13;
+ t21 += v * b14;
+ t22 += v * b15;
+ v = a[8];
+ t8 += v * b0;
+ t9 += v * b1;
+ t10 += v * b2;
+ t11 += v * b3;
+ t12 += v * b4;
+ t13 += v * b5;
+ t14 += v * b6;
+ t15 += v * b7;
+ t16 += v * b8;
+ t17 += v * b9;
+ t18 += v * b10;
+ t19 += v * b11;
+ t20 += v * b12;
+ t21 += v * b13;
+ t22 += v * b14;
+ t23 += v * b15;
+ v = a[9];
+ t9 += v * b0;
+ t10 += v * b1;
+ t11 += v * b2;
+ t12 += v * b3;
+ t13 += v * b4;
+ t14 += v * b5;
+ t15 += v * b6;
+ t16 += v * b7;
+ t17 += v * b8;
+ t18 += v * b9;
+ t19 += v * b10;
+ t20 += v * b11;
+ t21 += v * b12;
+ t22 += v * b13;
+ t23 += v * b14;
+ t24 += v * b15;
+ v = a[10];
+ t10 += v * b0;
+ t11 += v * b1;
+ t12 += v * b2;
+ t13 += v * b3;
+ t14 += v * b4;
+ t15 += v * b5;
+ t16 += v * b6;
+ t17 += v * b7;
+ t18 += v * b8;
+ t19 += v * b9;
+ t20 += v * b10;
+ t21 += v * b11;
+ t22 += v * b12;
+ t23 += v * b13;
+ t24 += v * b14;
+ t25 += v * b15;
+ v = a[11];
+ t11 += v * b0;
+ t12 += v * b1;
+ t13 += v * b2;
+ t14 += v * b3;
+ t15 += v * b4;
+ t16 += v * b5;
+ t17 += v * b6;
+ t18 += v * b7;
+ t19 += v * b8;
+ t20 += v * b9;
+ t21 += v * b10;
+ t22 += v * b11;
+ t23 += v * b12;
+ t24 += v * b13;
+ t25 += v * b14;
+ t26 += v * b15;
+ v = a[12];
+ t12 += v * b0;
+ t13 += v * b1;
+ t14 += v * b2;
+ t15 += v * b3;
+ t16 += v * b4;
+ t17 += v * b5;
+ t18 += v * b6;
+ t19 += v * b7;
+ t20 += v * b8;
+ t21 += v * b9;
+ t22 += v * b10;
+ t23 += v * b11;
+ t24 += v * b12;
+ t25 += v * b13;
+ t26 += v * b14;
+ t27 += v * b15;
+ v = a[13];
+ t13 += v * b0;
+ t14 += v * b1;
+ t15 += v * b2;
+ t16 += v * b3;
+ t17 += v * b4;
+ t18 += v * b5;
+ t19 += v * b6;
+ t20 += v * b7;
+ t21 += v * b8;
+ t22 += v * b9;
+ t23 += v * b10;
+ t24 += v * b11;
+ t25 += v * b12;
+ t26 += v * b13;
+ t27 += v * b14;
+ t28 += v * b15;
+ v = a[14];
+ t14 += v * b0;
+ t15 += v * b1;
+ t16 += v * b2;
+ t17 += v * b3;
+ t18 += v * b4;
+ t19 += v * b5;
+ t20 += v * b6;
+ t21 += v * b7;
+ t22 += v * b8;
+ t23 += v * b9;
+ t24 += v * b10;
+ t25 += v * b11;
+ t26 += v * b12;
+ t27 += v * b13;
+ t28 += v * b14;
+ t29 += v * b15;
+ v = a[15];
+ t15 += v * b0;
+ t16 += v * b1;
+ t17 += v * b2;
+ t18 += v * b3;
+ t19 += v * b4;
+ t20 += v * b5;
+ t21 += v * b6;
+ t22 += v * b7;
+ t23 += v * b8;
+ t24 += v * b9;
+ t25 += v * b10;
+ t26 += v * b11;
+ t27 += v * b12;
+ t28 += v * b13;
+ t29 += v * b14;
+ t30 += v * b15;
+ t0 += 38 * t16;
+ t1 += 38 * t17;
+ t2 += 38 * t18;
+ t3 += 38 * t19;
+ t4 += 38 * t20;
+ t5 += 38 * t21;
+ t6 += 38 * t22;
+ t7 += 38 * t23;
+ t8 += 38 * t24;
+ t9 += 38 * t25;
+ t10 += 38 * t26;
+ t11 += 38 * t27;
+ t12 += 38 * t28;
+ t13 += 38 * t29;
+ t14 += 38 * t30;
+ // t15 left as is
+ // first car
+ c = 1;
+ v = t0 + c + 65535;
+ c = Math.floor(v / 65536);
+ t0 = v - c * 65536;
+ v = t1 + c + 65535;
+ c = Math.floor(v / 65536);
+ t1 = v - c * 65536;
+ v = t2 + c + 65535;
+ c = Math.floor(v / 65536);
+ t2 = v - c * 65536;
+ v = t3 + c + 65535;
+ c = Math.floor(v / 65536);
+ t3 = v - c * 65536;
+ v = t4 + c + 65535;
+ c = Math.floor(v / 65536);
+ t4 = v - c * 65536;
+ v = t5 + c + 65535;
+ c = Math.floor(v / 65536);
+ t5 = v - c * 65536;
+ v = t6 + c + 65535;
+ c = Math.floor(v / 65536);
+ t6 = v - c * 65536;
+ v = t7 + c + 65535;
+ c = Math.floor(v / 65536);
+ t7 = v - c * 65536;
+ v = t8 + c + 65535;
+ c = Math.floor(v / 65536);
+ t8 = v - c * 65536;
+ v = t9 + c + 65535;
+ c = Math.floor(v / 65536);
+ t9 = v - c * 65536;
+ v = t10 + c + 65535;
+ c = Math.floor(v / 65536);
+ t10 = v - c * 65536;
+ v = t11 + c + 65535;
+ c = Math.floor(v / 65536);
+ t11 = v - c * 65536;
+ v = t12 + c + 65535;
+ c = Math.floor(v / 65536);
+ t12 = v - c * 65536;
+ v = t13 + c + 65535;
+ c = Math.floor(v / 65536);
+ t13 = v - c * 65536;
+ v = t14 + c + 65535;
+ c = Math.floor(v / 65536);
+ t14 = v - c * 65536;
+ v = t15 + c + 65535;
+ c = Math.floor(v / 65536);
+ t15 = v - c * 65536;
+ t0 += c - 1 + 37 * (c - 1);
+ // second car
+ c = 1;
+ v = t0 + c + 65535;
+ c = Math.floor(v / 65536);
+ t0 = v - c * 65536;
+ v = t1 + c + 65535;
+ c = Math.floor(v / 65536);
+ t1 = v - c * 65536;
+ v = t2 + c + 65535;
+ c = Math.floor(v / 65536);
+ t2 = v - c * 65536;
+ v = t3 + c + 65535;
+ c = Math.floor(v / 65536);
+ t3 = v - c * 65536;
+ v = t4 + c + 65535;
+ c = Math.floor(v / 65536);
+ t4 = v - c * 65536;
+ v = t5 + c + 65535;
+ c = Math.floor(v / 65536);
+ t5 = v - c * 65536;
+ v = t6 + c + 65535;
+ c = Math.floor(v / 65536);
+ t6 = v - c * 65536;
+ v = t7 + c + 65535;
+ c = Math.floor(v / 65536);
+ t7 = v - c * 65536;
+ v = t8 + c + 65535;
+ c = Math.floor(v / 65536);
+ t8 = v - c * 65536;
+ v = t9 + c + 65535;
+ c = Math.floor(v / 65536);
+ t9 = v - c * 65536;
+ v = t10 + c + 65535;
+ c = Math.floor(v / 65536);
+ t10 = v - c * 65536;
+ v = t11 + c + 65535;
+ c = Math.floor(v / 65536);
+ t11 = v - c * 65536;
+ v = t12 + c + 65535;
+ c = Math.floor(v / 65536);
+ t12 = v - c * 65536;
+ v = t13 + c + 65535;
+ c = Math.floor(v / 65536);
+ t13 = v - c * 65536;
+ v = t14 + c + 65535;
+ c = Math.floor(v / 65536);
+ t14 = v - c * 65536;
+ v = t15 + c + 65535;
+ c = Math.floor(v / 65536);
+ t15 = v - c * 65536;
+ t0 += c - 1 + 37 * (c - 1);
+ o[0] = t0;
+ o[1] = t1;
+ o[2] = t2;
+ o[3] = t3;
+ o[4] = t4;
+ o[5] = t5;
+ o[6] = t6;
+ o[7] = t7;
+ o[8] = t8;
+ o[9] = t9;
+ o[10] = t10;
+ o[11] = t11;
+ o[12] = t12;
+ o[13] = t13;
+ o[14] = t14;
+ o[15] = t15;
+}
+function S(o, a) {
+ M(o, a, a);
+}
+function inv25519(o, i) {
+ const c = gf();
+ let a;
+ for (a = 0; a < 16; a++)
+ c[a] = i[a];
+ for (a = 253; a >= 0; a--) {
+ S(c, c);
+ if (a !== 2 && a !== 4)
+ M(c, c, i);
+ }
+ for (a = 0; a < 16; a++)
+ o[a] = c[a];
+}
+function pow2523(o, i) {
+ const c = gf();
+ let a;
+ for (a = 0; a < 16; a++)
+ c[a] = i[a];
+ for (a = 250; a >= 0; a--) {
+ S(c, c);
+ if (a !== 1)
+ M(c, c, i);
+ }
+ for (a = 0; a < 16; a++)
+ o[a] = c[a];
+}
+function crypto_scalarmult(q, n, p) {
+ const z = new Uint8Array(32);
+ const x = new Float64Array(80);
+ let r;
+ let i;
+ const a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf();
+ for (i = 0; i < 31; i++)
+ z[i] = n[i];
+ z[31] = (n[31] & 127) | 64;
+ z[0] &= 248;
+ unpack25519(x, p);
+ for (i = 0; i < 16; i++) {
+ b[i] = x[i];
+ d[i] = a[i] = c[i] = 0;
+ }
+ a[0] = d[0] = 1;
+ for (i = 254; i >= 0; --i) {
+ r = (z[i >>> 3] >>> (i & 7)) & 1;
+ sel25519(a, b, r);
+ sel25519(c, d, r);
+ A(e, a, c);
+ Z(a, a, c);
+ A(c, b, d);
+ Z(b, b, d);
+ S(d, e);
+ S(f, a);
+ M(a, c, a);
+ M(c, b, e);
+ A(e, a, c);
+ Z(a, a, c);
+ S(b, a);
+ Z(c, d, f);
+ M(a, c, _121665);
+ A(a, a, d);
+ M(c, c, a);
+ M(a, d, f);
+ M(d, b, x);
+ S(b, e);
+ sel25519(a, b, r);
+ sel25519(c, d, r);
+ }
+ for (i = 0; i < 16; i++) {
+ x[i + 16] = a[i];
+ x[i + 32] = c[i];
+ x[i + 48] = b[i];
+ x[i + 64] = d[i];
+ }
+ const x32 = x.subarray(32);
+ const x16 = x.subarray(16);
+ inv25519(x32, x32);
+ M(x16, x16, x32);
+ pack25519(q, x16);
+ return 0;
+}
+function crypto_scalarmult_base(q, n) {
+ return crypto_scalarmult(q, n, _9);
+}
+// prettier-ignore
+const K$1 = [
+ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
+ 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
+ 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
+ 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
+ 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
+ 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
+ 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
+ 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
+ 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
+ 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
+ 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
+ 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
+ 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
+ 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
+ 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
+ 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
+ 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
+ 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
+ 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
+ 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
+ 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
+ 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
+ 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
+ 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
+ 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
+ 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
+ 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
+ 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
+ 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
+ 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
+ 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
+ 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
+ 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
+ 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
+ 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
+ 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
+ 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
+ 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
+ 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
+ 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
+];
+function crypto_hashblocks_hl(hh, hl, m, n) {
+ const wh = new Int32Array(16), wl = new Int32Array(16);
+ let bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h, l, a, b, c, d;
+ let ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
+ let pos = 0;
+ while (n >= 128) {
+ for (i = 0; i < 16; i++) {
+ j = 8 * i + pos;
+ wh[i] = (m[j + 0] << 24) | (m[j + 1] << 16) | (m[j + 2] << 8) | m[j + 3];
+ wl[i] = (m[j + 4] << 24) | (m[j + 5] << 16) | (m[j + 6] << 8) | m[j + 7];
+ }
+ for (i = 0; i < 80; i++) {
+ bh0 = ah0;
+ bh1 = ah1;
+ bh2 = ah2;
+ bh3 = ah3;
+ bh4 = ah4;
+ bh5 = ah5;
+ bh6 = ah6;
+ bh7 = ah7;
+ bl0 = al0;
+ bl1 = al1;
+ bl2 = al2;
+ bl3 = al3;
+ bl4 = al4;
+ bl5 = al5;
+ bl6 = al6;
+ bl7 = al7;
+ // add
+ h = ah7;
+ l = al7;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ // Sigma1
+ h =
+ ((ah4 >>> 14) | (al4 << (32 - 14))) ^
+ ((ah4 >>> 18) | (al4 << (32 - 18))) ^
+ ((al4 >>> (41 - 32)) | (ah4 << (32 - (41 - 32))));
+ l =
+ ((al4 >>> 14) | (ah4 << (32 - 14))) ^
+ ((al4 >>> 18) | (ah4 << (32 - 18))) ^
+ ((ah4 >>> (41 - 32)) | (al4 << (32 - (41 - 32))));
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // Ch
+ h = (ah4 & ah5) ^ (~ah4 & ah6);
+ l = (al4 & al5) ^ (~al4 & al6);
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // K
+ h = K$1[i * 2];
+ l = K$1[i * 2 + 1];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // w
+ h = wh[i % 16];
+ l = wl[i % 16];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ th = (c & 0xffff) | (d << 16);
+ tl = (a & 0xffff) | (b << 16);
+ // add
+ h = th;
+ l = tl;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ // Sigma0
+ h =
+ ((ah0 >>> 28) | (al0 << (32 - 28))) ^
+ ((al0 >>> (34 - 32)) | (ah0 << (32 - (34 - 32)))) ^
+ ((al0 >>> (39 - 32)) | (ah0 << (32 - (39 - 32))));
+ l =
+ ((al0 >>> 28) | (ah0 << (32 - 28))) ^
+ ((ah0 >>> (34 - 32)) | (al0 << (32 - (34 - 32)))) ^
+ ((ah0 >>> (39 - 32)) | (al0 << (32 - (39 - 32))));
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // Maj
+ h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2);
+ l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2);
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ bh7 = (c & 0xffff) | (d << 16);
+ bl7 = (a & 0xffff) | (b << 16);
+ // add
+ h = bh3;
+ l = bl3;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = th;
+ l = tl;
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ bh3 = (c & 0xffff) | (d << 16);
+ bl3 = (a & 0xffff) | (b << 16);
+ ah1 = bh0;
+ ah2 = bh1;
+ ah3 = bh2;
+ ah4 = bh3;
+ ah5 = bh4;
+ ah6 = bh5;
+ ah7 = bh6;
+ ah0 = bh7;
+ al1 = bl0;
+ al2 = bl1;
+ al3 = bl2;
+ al4 = bl3;
+ al5 = bl4;
+ al6 = bl5;
+ al7 = bl6;
+ al0 = bl7;
+ if (i % 16 === 15) {
+ for (j = 0; j < 16; j++) {
+ // add
+ h = wh[j];
+ l = wl[j];
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = wh[(j + 9) % 16];
+ l = wl[(j + 9) % 16];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // sigma0
+ th = wh[(j + 1) % 16];
+ tl = wl[(j + 1) % 16];
+ h =
+ ((th >>> 1) | (tl << (32 - 1))) ^
+ ((th >>> 8) | (tl << (32 - 8))) ^
+ (th >>> 7);
+ l =
+ ((tl >>> 1) | (th << (32 - 1))) ^
+ ((tl >>> 8) | (th << (32 - 8))) ^
+ ((tl >>> 7) | (th << (32 - 7)));
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ // sigma1
+ th = wh[(j + 14) % 16];
+ tl = wl[(j + 14) % 16];
+ h =
+ ((th >>> 19) | (tl << (32 - 19))) ^
+ ((tl >>> (61 - 32)) | (th << (32 - (61 - 32)))) ^
+ (th >>> 6);
+ l =
+ ((tl >>> 19) | (th << (32 - 19))) ^
+ ((th >>> (61 - 32)) | (tl << (32 - (61 - 32)))) ^
+ ((tl >>> 6) | (th << (32 - 6)));
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ wh[j] = (c & 0xffff) | (d << 16);
+ wl[j] = (a & 0xffff) | (b << 16);
+ }
+ }
+ }
+ // add
+ h = ah0;
+ l = al0;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[0];
+ l = hl[0];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[0] = ah0 = (c & 0xffff) | (d << 16);
+ hl[0] = al0 = (a & 0xffff) | (b << 16);
+ h = ah1;
+ l = al1;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[1];
+ l = hl[1];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[1] = ah1 = (c & 0xffff) | (d << 16);
+ hl[1] = al1 = (a & 0xffff) | (b << 16);
+ h = ah2;
+ l = al2;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[2];
+ l = hl[2];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[2] = ah2 = (c & 0xffff) | (d << 16);
+ hl[2] = al2 = (a & 0xffff) | (b << 16);
+ h = ah3;
+ l = al3;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[3];
+ l = hl[3];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[3] = ah3 = (c & 0xffff) | (d << 16);
+ hl[3] = al3 = (a & 0xffff) | (b << 16);
+ h = ah4;
+ l = al4;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[4];
+ l = hl[4];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[4] = ah4 = (c & 0xffff) | (d << 16);
+ hl[4] = al4 = (a & 0xffff) | (b << 16);
+ h = ah5;
+ l = al5;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[5];
+ l = hl[5];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[5] = ah5 = (c & 0xffff) | (d << 16);
+ hl[5] = al5 = (a & 0xffff) | (b << 16);
+ h = ah6;
+ l = al6;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[6];
+ l = hl[6];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[6] = ah6 = (c & 0xffff) | (d << 16);
+ hl[6] = al6 = (a & 0xffff) | (b << 16);
+ h = ah7;
+ l = al7;
+ a = l & 0xffff;
+ b = l >>> 16;
+ c = h & 0xffff;
+ d = h >>> 16;
+ h = hh[7];
+ l = hl[7];
+ a += l & 0xffff;
+ b += l >>> 16;
+ c += h & 0xffff;
+ d += h >>> 16;
+ b += a >>> 16;
+ c += b >>> 16;
+ d += c >>> 16;
+ hh[7] = ah7 = (c & 0xffff) | (d << 16);
+ hl[7] = al7 = (a & 0xffff) | (b << 16);
+ pos += 128;
+ n -= 128;
+ }
+ return n;
+}
+function crypto_hash(out, m, n) {
+ const hh = new Int32Array(8);
+ const hl = new Int32Array(8);
+ const x = new Uint8Array(256);
+ const b = n;
+ hh[0] = 0x6a09e667;
+ hh[1] = 0xbb67ae85;
+ hh[2] = 0x3c6ef372;
+ hh[3] = 0xa54ff53a;
+ hh[4] = 0x510e527f;
+ hh[5] = 0x9b05688c;
+ hh[6] = 0x1f83d9ab;
+ hh[7] = 0x5be0cd19;
+ hl[0] = 0xf3bcc908;
+ hl[1] = 0x84caa73b;
+ hl[2] = 0xfe94f82b;
+ hl[3] = 0x5f1d36f1;
+ hl[4] = 0xade682d1;
+ hl[5] = 0x2b3e6c1f;
+ hl[6] = 0xfb41bd6b;
+ hl[7] = 0x137e2179;
+ crypto_hashblocks_hl(hh, hl, m, n);
+ n %= 128;
+ for (let i = 0; i < n; i++)
+ x[i] = m[b - n + i];
+ x[n] = 128;
+ n = 256 - 128 * (n < 112 ? 1 : 0);
+ x[n - 9] = 0;
+ ts64(x, n - 8, (b / 0x20000000) | 0, b << 3);
+ crypto_hashblocks_hl(hh, hl, x, n);
+ for (let i = 0; i < 8; i++)
+ ts64(out, 8 * i, hh[i], hl[i]);
+ return 0;
+}
+/**
+ * Incremental version of crypto_hash.
+ */
+class HashState {
+ constructor() {
+ this.hh = new Int32Array(8);
+ this.hl = new Int32Array(8);
+ this.next = new Uint8Array(128);
+ this.p = 0;
+ this.total = 0;
+ this.hh[0] = 0x6a09e667;
+ this.hh[1] = 0xbb67ae85;
+ this.hh[2] = 0x3c6ef372;
+ this.hh[3] = 0xa54ff53a;
+ this.hh[4] = 0x510e527f;
+ this.hh[5] = 0x9b05688c;
+ this.hh[6] = 0x1f83d9ab;
+ this.hh[7] = 0x5be0cd19;
+ this.hl[0] = 0xf3bcc908;
+ this.hl[1] = 0x84caa73b;
+ this.hl[2] = 0xfe94f82b;
+ this.hl[3] = 0x5f1d36f1;
+ this.hl[4] = 0xade682d1;
+ this.hl[5] = 0x2b3e6c1f;
+ this.hl[6] = 0xfb41bd6b;
+ this.hl[7] = 0x137e2179;
+ }
+ update(data) {
+ this.total += data.length;
+ let i = 0;
+ while (i < data.length) {
+ const r = 128 - this.p;
+ if (r > data.length - i) {
+ for (let j = 0; i + j < data.length; j++) {
+ this.next[this.p + j] = data[i + j];
+ }
+ this.p += data.length - i;
+ break;
+ }
+ else {
+ for (let j = 0; this.p + j < 128; j++) {
+ this.next[this.p + j] = data[i + j];
+ }
+ crypto_hashblocks_hl(this.hh, this.hl, this.next, 128);
+ i += 128 - this.p;
+ this.p = 0;
+ }
+ }
+ return this;
+ }
+ finish() {
+ const out = new Uint8Array(64);
+ let n = this.p;
+ const x = new Uint8Array(256);
+ const b = this.total;
+ for (let i = 0; i < n; i++)
+ x[i] = this.next[i];
+ x[n] = 128;
+ n = 256 - 128 * (n < 112 ? 1 : 0);
+ x[n - 9] = 0;
+ ts64(x, n - 8, (b / 0x20000000) | 0, b << 3);
+ crypto_hashblocks_hl(this.hh, this.hl, x, n);
+ for (let i = 0; i < 8; i++)
+ ts64(out, 8 * i, this.hh[i], this.hl[i]);
+ return out;
+ }
+}
+function add(p, q) {
+ const a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf();
+ Z(a, p[1], p[0]);
+ Z(t, q[1], q[0]);
+ M(a, a, t);
+ A(b, p[0], p[1]);
+ A(t, q[0], q[1]);
+ M(b, b, t);
+ M(c, p[3], q[3]);
+ M(c, c, D2);
+ M(d, p[2], q[2]);
+ A(d, d, d);
+ Z(e, b, a);
+ Z(f, d, c);
+ A(g, d, c);
+ A(h, b, a);
+ M(p[0], e, f);
+ M(p[1], h, g);
+ M(p[2], g, f);
+ M(p[3], e, h);
+}
+function cswap(p, q, b) {
+ let i;
+ for (i = 0; i < 4; i++) {
+ sel25519(p[i], q[i], b);
+ }
+}
+function pack(r, p) {
+ const tx = gf(), ty = gf(), zi = gf();
+ inv25519(zi, p[2]);
+ M(tx, p[0], zi);
+ M(ty, p[1], zi);
+ pack25519(r, ty);
+ r[31] ^= par25519(tx) << 7;
+}
+/**
+ * Ed25519 scalar multiplication
+ */
+function scalarmult(p, q, s) {
+ let b, i;
+ set25519(p[0], gf0);
+ set25519(p[1], gf1);
+ set25519(p[2], gf1);
+ set25519(p[3], gf0);
+ for (i = 255; i >= 0; --i) {
+ b = (s[(i / 8) | 0] >> (i & 7)) & 1;
+ cswap(p, q, b);
+ add(q, p);
+ add(p, p);
+ cswap(p, q, b);
+ }
+}
+function scalarbase(p, s) {
+ const q = [gf(), gf(), gf(), gf()];
+ set25519(q[0], X);
+ set25519(q[1], Y);
+ set25519(q[2], gf1);
+ M(q[3], X, Y);
+ scalarmult(p, q, s);
+}
+function crypto_sign_keypair(pk, sk, seeded) {
+ const d = new Uint8Array(64);
+ const p = [gf(), gf(), gf(), gf()];
+ if (!seeded)
+ randombytes(sk, 32);
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+ scalarbase(p, d);
+ pack(pk, p);
+ for (let i = 0; i < 32; i++)
+ sk[i + 32] = pk[i];
+ return 0;
+}
+const L = new Float64Array([
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde,
+ 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10,
+]);
+function modL(r, x) {
+ let carry, i, j, k;
+ for (i = 63; i >= 32; --i) {
+ carry = 0;
+ for (j = i - 32, k = i - 12; j < k; ++j) {
+ x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+ carry = Math.floor((x[j] + 128) / 256);
+ x[j] -= carry * 256;
+ }
+ x[j] += carry;
+ x[i] = 0;
+ }
+ carry = 0;
+ for (j = 0; j < 32; j++) {
+ x[j] += carry - (x[31] >> 4) * L[j];
+ carry = x[j] >> 8;
+ x[j] &= 255;
+ }
+ for (j = 0; j < 32; j++)
+ x[j] -= carry * L[j];
+ for (i = 0; i < 32; i++) {
+ x[i + 1] += x[i] >> 8;
+ r[i] = x[i] & 255;
+ }
+}
+function reduce(r) {
+ const x = new Float64Array(64);
+ for (let i = 0; i < 64; i++)
+ x[i] = r[i];
+ for (let i = 0; i < 64; i++)
+ r[i] = 0;
+ modL(r, x);
+}
+// Note: difference from C - smlen returned, not passed as argument.
+function crypto_sign(sm, m, n, sk) {
+ const d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
+ let i, j;
+ const x = new Float64Array(64);
+ const p = [gf(), gf(), gf(), gf()];
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+ const smlen = n + 64;
+ for (i = 0; i < n; i++)
+ sm[64 + i] = m[i];
+ for (i = 0; i < 32; i++)
+ sm[32 + i] = d[32 + i];
+ crypto_hash(r, sm.subarray(32), n + 32);
+ reduce(r);
+ scalarbase(p, r);
+ pack(sm, p);
+ for (i = 32; i < 64; i++)
+ sm[i] = sk[i];
+ crypto_hash(h, sm, n + 64);
+ reduce(h);
+ for (i = 0; i < 64; i++)
+ x[i] = 0;
+ for (i = 0; i < 32; i++)
+ x[i] = r[i];
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 32; j++) {
+ x[i + j] += h[i] * d[j];
+ }
+ }
+ modL(sm.subarray(32), x);
+ return smlen;
+}
+function unpackpos(r, p) {
+ // FIXME: implement directly
+ const q = [gf(), gf(), gf(), gf()];
+ if (unpackneg(q, p))
+ return -1;
+ const scalar0 = new Uint8Array(32);
+ const scalar1 = new Uint8Array(32);
+ scalar1[0] = 1;
+ const scalarNeg1 = crypto_core_ed25519_scalar_sub(scalar0, scalar1);
+ scalarmult(r, q, scalarNeg1);
+ return 0;
+}
+function unpackneg(r, p) {
+ const t = gf();
+ const chk = gf();
+ const num = gf();
+ const den = gf();
+ const den2 = gf();
+ const den4 = gf();
+ const den6 = gf();
+ set25519(r[2], gf1);
+ unpack25519(r[1], p);
+ S(num, r[1]);
+ M(den, num, D);
+ Z(num, num, r[2]);
+ A(den, r[2], den);
+ S(den2, den);
+ S(den4, den2);
+ M(den6, den4, den2);
+ M(t, den6, num);
+ M(t, t, den);
+ pow2523(t, t);
+ M(t, t, num);
+ M(t, t, den);
+ M(t, t, den);
+ M(r[0], t, den);
+ S(chk, r[0]);
+ M(chk, chk, den);
+ if (neq25519(chk, num))
+ M(r[0], r[0], I);
+ S(chk, r[0]);
+ M(chk, chk, den);
+ if (neq25519(chk, num))
+ return -1;
+ if (par25519(r[0]) === p[31] >> 7)
+ Z(r[0], gf0, r[0]);
+ M(r[3], r[0], r[1]);
+ return 0;
+}
+function crypto_scalarmult_ed25519_base_noclamp(s) {
+ const r = new Uint8Array(32);
+ const p = [gf(), gf(), gf(), gf()];
+ scalarbase(p, s);
+ pack(r, p);
+ return r;
+}
+function crypto_scalarmult_ed25519_noclamp(s, q) {
+ const r = new Uint8Array(32);
+ const p = [gf(), gf(), gf(), gf()];
+ const ql = [gf(), gf(), gf(), gf()];
+ if (unpackpos(ql, q))
+ throw new Error();
+ scalarmult(p, ql, s);
+ pack(r, p);
+ return r;
+}
+function crypto_sign_open(m, sm, n, pk) {
+ let i, mlen;
+ const t = new Uint8Array(32), h = new Uint8Array(64);
+ const p = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()];
+ mlen = -1;
+ if (n < 64)
+ return -1;
+ if (unpackneg(q, pk))
+ return -1;
+ for (i = 0; i < n; i++)
+ m[i] = sm[i];
+ for (i = 0; i < 32; i++)
+ m[i + 32] = pk[i];
+ crypto_hash(h, m, n);
+ reduce(h);
+ scalarmult(p, q, h);
+ scalarbase(q, sm.subarray(32));
+ add(p, q);
+ pack(t, p);
+ n -= 64;
+ if (crypto_verify_32(sm, 0, t, 0)) {
+ for (i = 0; i < n; i++)
+ m[i] = 0;
+ return -1;
+ }
+ for (i = 0; i < n; i++)
+ m[i] = sm[i + 64];
+ mlen = n;
+ return mlen;
+}
+const crypto_secretbox_KEYBYTES = 32;
+const crypto_secretbox_NONCEBYTES = 24;
+const crypto_secretbox_ZEROBYTES = 32;
+const crypto_secretbox_BOXZEROBYTES = 16;
+const crypto_scalarmult_BYTES = 32;
+const crypto_scalarmult_SCALARBYTES = 32;
+const crypto_sign_BYTES = 64;
+const crypto_sign_PUBLICKEYBYTES = 32;
+const crypto_sign_SECRETKEYBYTES = 64;
+const crypto_sign_SEEDBYTES = 32;
+const crypto_hash_BYTES = 64;
+/* High-level API */
+function checkLengths(k, n) {
+ if (k.length !== crypto_secretbox_KEYBYTES)
+ throw new Error("bad key size");
+ if (n.length !== crypto_secretbox_NONCEBYTES)
+ throw new Error("bad nonce size");
+}
+function checkArrayTypes(...args) {
+ for (let i = 0; i < args.length; i++) {
+ if (!(args[i] instanceof Uint8Array))
+ throw new TypeError("unexpected type, use Uint8Array");
+ }
+}
+function randomBytes(n) {
+ const b = new Uint8Array(n);
+ randombytes(b, n);
+ return b;
+}
+function scalarMult(n, p) {
+ checkArrayTypes(n, p);
+ if (n.length !== crypto_scalarmult_SCALARBYTES)
+ throw new Error("bad n size");
+ if (p.length !== crypto_scalarmult_BYTES)
+ throw new Error("bad p size");
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
+ crypto_scalarmult(q, n, p);
+ return q;
+}
+function scalarMult_base(n) {
+ checkArrayTypes(n);
+ if (n.length !== crypto_scalarmult_SCALARBYTES)
+ throw new Error("bad n size");
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
+ crypto_scalarmult_base(q, n);
+ return q;
+}
+function sign(msg, secretKey) {
+ checkArrayTypes(msg, secretKey);
+ if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
+ throw new Error("bad secret key size");
+ const signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
+ crypto_sign(signedMsg, msg, msg.length, secretKey);
+ return signedMsg;
+}
+function sign_detached(msg, secretKey) {
+ const signedMsg = sign(msg, secretKey);
+ const sig = new Uint8Array(crypto_sign_BYTES);
+ for (let i = 0; i < sig.length; i++)
+ sig[i] = signedMsg[i];
+ return sig;
+}
+function sign_detached_verify(msg, sig, publicKey) {
+ checkArrayTypes(msg, sig, publicKey);
+ if (sig.length !== crypto_sign_BYTES)
+ throw new Error("bad signature size");
+ if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
+ throw new Error("bad public key size");
+ const sm = new Uint8Array(crypto_sign_BYTES + msg.length);
+ const m = new Uint8Array(crypto_sign_BYTES + msg.length);
+ let i;
+ for (i = 0; i < crypto_sign_BYTES; i++)
+ sm[i] = sig[i];
+ for (i = 0; i < msg.length; i++)
+ sm[i + crypto_sign_BYTES] = msg[i];
+ return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
+}
+function crypto_sign_keyPair_fromSeed(seed) {
+ checkArrayTypes(seed);
+ if (seed.length !== crypto_sign_SEEDBYTES)
+ throw new Error(`bad seed size: ${seed.length}`);
+ const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ const sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
+ for (let i = 0; i < 32; i++)
+ sk[i] = seed[i];
+ crypto_sign_keypair(pk, sk, true);
+ return { publicKey: pk, secretKey: sk };
+}
+function hash$1(msg) {
+ checkArrayTypes(msg);
+ const h = new Uint8Array(crypto_hash_BYTES);
+ crypto_hash(h, msg, msg.length);
+ return h;
+}
+function setPRNG(fn) {
+ randombytes = fn;
+}
+function sign_ed25519_pk_to_curve25519(ed25519_pk) {
+ const ge_a = [gf(), gf(), gf(), gf()];
+ const x = gf();
+ const one_minus_y = gf();
+ const x25519_pk = new Uint8Array(32);
+ if (unpackneg(ge_a, ed25519_pk)) {
+ throw Error("invalid public key");
+ }
+ set25519(one_minus_y, gf1);
+ Z(one_minus_y, one_minus_y, ge_a[1]);
+ set25519(x, gf1);
+ A(x, x, ge_a[1]);
+ inv25519(one_minus_y, one_minus_y);
+ M(x, x, one_minus_y);
+ pack25519(x25519_pk, x);
+ return x25519_pk;
+}
+function secretbox(msg, nonce, key) {
+ checkArrayTypes(msg, nonce, key);
+ checkLengths(key, nonce);
+ var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
+ var c = new Uint8Array(m.length);
+ for (var i = 0; i < msg.length; i++)
+ m[i + crypto_secretbox_ZEROBYTES] = msg[i];
+ crypto_secretbox(c, m, m.length, nonce, key);
+ return c.subarray(crypto_secretbox_BOXZEROBYTES);
+}
+function secretbox_open(box, nonce, key) {
+ checkArrayTypes(box, nonce, key);
+ checkLengths(key, nonce);
+ var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
+ var m = new Uint8Array(c.length);
+ for (var i = 0; i < box.length; i++)
+ c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
+ if (c.length < 32)
+ return undefined;
+ if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0)
+ return undefined;
+ return m.subarray(crypto_secretbox_ZEROBYTES);
+}
+/**
+ * Reduce a scalar "s" to "s mod L". The input can be up to 64 bytes long.
+ */
+function crypto_core_ed25519_scalar_reduce(x) {
+ const len = x.length;
+ const z = new Float64Array(64);
+ for (let i = 0; i < len; i++)
+ z[i] = x[i];
+ const o = new Uint8Array(32);
+ modL(o, z);
+ return o;
+}
+function crypto_core_ed25519_scalar_sub(x, y) {
+ const z = new Float64Array(64);
+ for (let i = 0; i < 32; i++) {
+ z[i] = x[i] - y[i];
+ }
+ const o = new Uint8Array(32);
+ modL(o, z);
+ return o;
+}
+function crypto_edx25519_private_key_create() {
+ const seed = new Uint8Array(32);
+ randombytes(seed, 32);
+ return crypto_edx25519_private_key_create_from_seed(seed);
+}
+function crypto_edx25519_private_key_create_from_seed(seed) {
+ const pk = hash$1(seed);
+ pk[0] &= 248;
+ pk[31] &= 127;
+ pk[31] |= 64;
+ return pk;
+}
+function crypto_edx25519_get_public(priv) {
+ return crypto_scalarmult_ed25519_base_noclamp(priv.subarray(0, 32));
+}
+function crypto_edx25519_sign_detached(m, skx, pkx) {
+ const n = m.length;
+ const h = new Uint8Array(64);
+ const r = new Uint8Array(64);
+ let i, j;
+ const x = new Float64Array(64);
+ const p = [gf(), gf(), gf(), gf()];
+ const sm = new Uint8Array(n + 64);
+ for (i = 0; i < n; i++)
+ sm[64 + i] = m[i];
+ for (i = 0; i < 32; i++)
+ sm[32 + i] = skx[32 + i];
+ crypto_hash(r, sm.subarray(32), n + 32);
+ reduce(r);
+ scalarbase(p, r);
+ pack(sm, p);
+ for (i = 32; i < 64; i++)
+ sm[i] = pkx[i - 32];
+ crypto_hash(h, sm, n + 64);
+ reduce(h);
+ for (i = 0; i < 64; i++)
+ x[i] = 0;
+ for (i = 0; i < 32; i++)
+ x[i] = r[i];
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 32; j++) {
+ x[i + j] += h[i] * skx[j];
+ }
+ }
+ modL(sm.subarray(32), x);
+ return sm.subarray(0, 64);
+}
+function crypto_edx25519_sign_detached_verify(msg, sig, publicKey) {
+ checkArrayTypes(msg, sig, publicKey);
+ if (sig.length !== crypto_sign_BYTES)
+ throw new Error("bad signature size");
+ if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
+ throw new Error("bad public key size");
+ const sm = new Uint8Array(crypto_sign_BYTES + msg.length);
+ const m = new Uint8Array(crypto_sign_BYTES + msg.length);
+ let i;
+ for (i = 0; i < crypto_sign_BYTES; i++)
+ sm[i] = sig[i];
+ for (i = 0; i < msg.length; i++)
+ sm[i + crypto_sign_BYTES] = msg[i];
+ return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+function initNodePrng() {
+ // Initialize PRNG if environment provides CSPRNG.
+ // If not, methods calling randombytes will throw.
+ if (cr__default["default"] && cr__default["default"].randomBytes) {
+ setPRNG(function (x, n) {
+ const v = cr__default["default"].randomBytes(n);
+ for (let i = 0; i < n; i++)
+ x[i] = v[i];
+ for (let i = 0; i < v.length; i++)
+ v[i] = 0;
+ });
+ }
+}
+
+/*
+ This file is part of GNU Taler
+ Copyright (C) 2012-2020 Taler Systems SA
+
+ GNU Taler is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNU 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: LGPL3.0-or-later
+
+ Note: the LGPL does not apply to all components of GNU Taler,
+ but it does apply to this file.
+ */
+var TalerErrorCode;
+(function (TalerErrorCode) {
+ /**
+ * Special code to indicate success (no error).
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["NONE"] = 0] = "NONE";
+ /**
+ * A non-integer error code was returned in the JSON response.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["INVALID"] = 1] = "INVALID";
+ /**
+ * An internal failure happened on the client side.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_CLIENT_INTERNAL_ERROR"] = 2] = "GENERIC_CLIENT_INTERNAL_ERROR";
+ /**
+ * The response we got from the server was not even in JSON format.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_INVALID_RESPONSE"] = 10] = "GENERIC_INVALID_RESPONSE";
+ /**
+ * An operation timed out.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_TIMEOUT"] = 11] = "GENERIC_TIMEOUT";
+ /**
+ * The version string given does not follow the expected CURRENT:REVISION:AGE Format.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_VERSION_MALFORMED"] = 12] = "GENERIC_VERSION_MALFORMED";
+ /**
+ * The service responded with a reply that was in JSON but did not satsify the protocol. Note that invalid cryptographic signatures should have signature-specific error codes.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_REPLY_MALFORMED"] = 13] = "GENERIC_REPLY_MALFORMED";
+ /**
+ * There is an error in the client-side configuration, for example the base URL specified is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_CONFIGURATION_INVALID"] = 14] = "GENERIC_CONFIGURATION_INVALID";
+ /**
+ * The client made a request to a service, but received an error response it does not know how to handle.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_UNEXPECTED_REQUEST_ERROR"] = 15] = "GENERIC_UNEXPECTED_REQUEST_ERROR";
+ /**
+ * The HTTP method used is invalid for this endpoint.
+ * Returned with an HTTP status code of #MHD_HTTP_METHOD_NOT_ALLOWED (405).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_METHOD_INVALID"] = 20] = "GENERIC_METHOD_INVALID";
+ /**
+ * There is no endpoint defined for the URL provided by the client.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_ENDPOINT_UNKNOWN"] = 21] = "GENERIC_ENDPOINT_UNKNOWN";
+ /**
+ * The JSON in the client's request was malformed (generic parse error).
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_JSON_INVALID"] = 22] = "GENERIC_JSON_INVALID";
+ /**
+ * Some of the HTTP headers provided by the client caused the server to not be able to handle the request.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_HTTP_HEADERS_MALFORMED"] = 23] = "GENERIC_HTTP_HEADERS_MALFORMED";
+ /**
+ * The payto:// URI provided by the client is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_PAYTO_URI_MALFORMED"] = 24] = "GENERIC_PAYTO_URI_MALFORMED";
+ /**
+ * A required parameter in the request was missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_PARAMETER_MISSING"] = 25] = "GENERIC_PARAMETER_MISSING";
+ /**
+ * A parameter in the request was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_PARAMETER_MALFORMED"] = 26] = "GENERIC_PARAMETER_MALFORMED";
+ /**
+ * The reserve public key given as part of a /reserves/ endpoint was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_RESERVE_PUB_MALFORMED"] = 27] = "GENERIC_RESERVE_PUB_MALFORMED";
+ /**
+ * The currencies involved in the operation do not match.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_CURRENCY_MISMATCH"] = 30] = "GENERIC_CURRENCY_MISMATCH";
+ /**
+ * The URI is longer than the longest URI the HTTP server is willing to parse.
+ * Returned with an HTTP status code of #MHD_HTTP_URI_TOO_LONG (414).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_URI_TOO_LONG"] = 31] = "GENERIC_URI_TOO_LONG";
+ /**
+ * The body is too large to be permissible for the endpoint.
+ * Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_UPLOAD_EXCEEDS_LIMIT"] = 32] = "GENERIC_UPLOAD_EXCEEDS_LIMIT";
+ /**
+ * The service failed initialize its connection to the database.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_SETUP_FAILED"] = 50] = "GENERIC_DB_SETUP_FAILED";
+ /**
+ * The service encountered an error event to just start the database transaction.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_START_FAILED"] = 51] = "GENERIC_DB_START_FAILED";
+ /**
+ * The service failed to store information in its database.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_STORE_FAILED"] = 52] = "GENERIC_DB_STORE_FAILED";
+ /**
+ * The service failed to fetch information from its database.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_FETCH_FAILED"] = 53] = "GENERIC_DB_FETCH_FAILED";
+ /**
+ * The service encountered an error event to commit the database transaction (hard, unrecoverable error).
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_COMMIT_FAILED"] = 54] = "GENERIC_DB_COMMIT_FAILED";
+ /**
+ * The service encountered an error event to commit the database transaction, even after repeatedly retrying it there was always a conflicting transaction. (This indicates a repeated serialization error; should only happen if some client maliciously tries to create conflicting concurrent transactions.)
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_SOFT_FAILURE"] = 55] = "GENERIC_DB_SOFT_FAILURE";
+ /**
+ * The service's database is inconsistent and violates service-internal invariants.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_DB_INVARIANT_FAILURE"] = 56] = "GENERIC_DB_INVARIANT_FAILURE";
+ /**
+ * The HTTP server experienced an internal invariant failure (bug).
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_INTERNAL_INVARIANT_FAILURE"] = 60] = "GENERIC_INTERNAL_INVARIANT_FAILURE";
+ /**
+ * The service could not compute a cryptographic hash over some JSON value.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_FAILED_COMPUTE_JSON_HASH"] = 61] = "GENERIC_FAILED_COMPUTE_JSON_HASH";
+ /**
+ * The service could not compute an amount.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_FAILED_COMPUTE_AMOUNT"] = 62] = "GENERIC_FAILED_COMPUTE_AMOUNT";
+ /**
+ * The HTTP server had insufficient memory to parse the request.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_PARSER_OUT_OF_MEMORY"] = 70] = "GENERIC_PARSER_OUT_OF_MEMORY";
+ /**
+ * The HTTP server failed to allocate memory.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_ALLOCATION_FAILURE"] = 71] = "GENERIC_ALLOCATION_FAILURE";
+ /**
+ * The HTTP server failed to allocate memory for building JSON reply.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_JSON_ALLOCATION_FAILURE"] = 72] = "GENERIC_JSON_ALLOCATION_FAILURE";
+ /**
+ * The HTTP server failed to allocate memory for making a CURL request.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_CURL_ALLOCATION_FAILURE"] = 73] = "GENERIC_CURL_ALLOCATION_FAILURE";
+ /**
+ * The backend could not locate a required template to generate an HTML reply.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_FAILED_TO_LOAD_TEMPLATE"] = 74] = "GENERIC_FAILED_TO_LOAD_TEMPLATE";
+ /**
+ * The backend could not expand the template to generate an HTML reply.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["GENERIC_FAILED_TO_EXPAND_TEMPLATE"] = 75] = "GENERIC_FAILED_TO_EXPAND_TEMPLATE";
+ /**
+ * Exchange is badly configured and thus cannot operate.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_BAD_CONFIGURATION"] = 1000] = "EXCHANGE_GENERIC_BAD_CONFIGURATION";
+ /**
+ * Operation specified unknown for this endpoint.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_OPERATION_UNKNOWN"] = 1001] = "EXCHANGE_GENERIC_OPERATION_UNKNOWN";
+ /**
+ * The number of segments included in the URI does not match the number of segments expected by the endpoint.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS"] = 1002] = "EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS";
+ /**
+ * The same coin was already used with a different denomination previously.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY"] = 1003] = "EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY";
+ /**
+ * The public key of given to a "/coins/" endpoint of the exchange was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB"] = 1004] = "EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB";
+ /**
+ * The exchange is not aware of the denomination key the wallet requested for the operation.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN"] = 1005] = "EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN";
+ /**
+ * The signature of the denomination key over the coin is not valid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_SIGNATURE_INVALID"] = 1006] = "EXCHANGE_DENOMINATION_SIGNATURE_INVALID";
+ /**
+ * The exchange failed to perform the operation as it could not find the private keys. This is a problem with the exchange setup, not with the client's request.
+ * Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_KEYS_MISSING"] = 1007] = "EXCHANGE_GENERIC_KEYS_MISSING";
+ /**
+ * Validity period of the denomination lies in the future.
+ * Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE"] = 1008] = "EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE";
+ /**
+ * Denomination key of the coin is past its expiration time for the requested operation.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_EXPIRED"] = 1009] = "EXCHANGE_GENERIC_DENOMINATION_EXPIRED";
+ /**
+ * Denomination key of the coin has been revoked.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_DENOMINATION_REVOKED"] = 1010] = "EXCHANGE_GENERIC_DENOMINATION_REVOKED";
+ /**
+ * An operation where the exchange interacted with a security module timed out.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_SECMOD_TIMEOUT"] = 1011] = "EXCHANGE_GENERIC_SECMOD_TIMEOUT";
+ /**
+ * The respective coin did not have sufficient residual value for the operation. The "history" in this response provides the "residual_value" of the coin, which may be less than its "original_value".
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_INSUFFICIENT_FUNDS"] = 1012] = "EXCHANGE_GENERIC_INSUFFICIENT_FUNDS";
+ /**
+ * The exchange had an internal error reconstructing the transaction history of the coin that was being processed.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_HISTORY_COMPUTATION_FAILED"] = 1013] = "EXCHANGE_GENERIC_COIN_HISTORY_COMPUTATION_FAILED";
+ /**
+ * The exchange failed to obtain the transaction history of the given coin from the database while generating an insufficient funds errors.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS"] = 1014] = "EXCHANGE_GENERIC_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS";
+ /**
+ * The same coin was already used with a different age hash previously.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH"] = 1015] = "EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH";
+ /**
+ * The requested operation is not valid for the cipher used by the selected denomination.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION"] = 1016] = "EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION";
+ /**
+ * The provided arguments for the operation use inconsistent ciphers.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_CIPHER_MISMATCH"] = 1017] = "EXCHANGE_GENERIC_CIPHER_MISMATCH";
+ /**
+ * The number of denominations specified in the request exceeds the limit of the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE"] = 1018] = "EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE";
+ /**
+ * The time at the server is too far off from the time specified in the request. Most likely the client system time is wrong.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_CLOCK_SKEW"] = 1020] = "EXCHANGE_GENERIC_CLOCK_SKEW";
+ /**
+ * The specified amount for the coin is higher than the value of the denomination of the coin.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE"] = 1021] = "EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE";
+ /**
+ * The exchange was not properly configured with global fees.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_GLOBAL_FEES_MISSING"] = 1022] = "EXCHANGE_GENERIC_GLOBAL_FEES_MISSING";
+ /**
+ * The exchange was not properly configured with wire fees.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_WIRE_FEES_MISSING"] = 1023] = "EXCHANGE_GENERIC_WIRE_FEES_MISSING";
+ /**
+ * The purse public key was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_PURSE_PUB_MALFORMED"] = 1024] = "EXCHANGE_GENERIC_PURSE_PUB_MALFORMED";
+ /**
+ * The purse is unknown.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_PURSE_UNKNOWN"] = 1025] = "EXCHANGE_GENERIC_PURSE_UNKNOWN";
+ /**
+ * The purse has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_PURSE_EXPIRED"] = 1026] = "EXCHANGE_GENERIC_PURSE_EXPIRED";
+ /**
+ * The exchange has no information about the "reserve_pub" that was given.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_RESERVE_UNKNOWN"] = 1027] = "EXCHANGE_GENERIC_RESERVE_UNKNOWN";
+ /**
+ * The exchange is not allowed to proceed with the operation until the client has satisfied a KYC check.
+ * Returned with an HTTP status code of #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS (451).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_GENERIC_KYC_REQUIRED"] = 1028] = "EXCHANGE_GENERIC_KYC_REQUIRED";
+ /**
+ * Inconsistency between provided age commitment and attest: either none or both must be provided
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_DEPOSIT_COIN_CONFLICTING_ATTEST_VS_AGE_COMMITMENT"] = 1029] = "EXCHANGE_PURSE_DEPOSIT_COIN_CONFLICTING_ATTEST_VS_AGE_COMMITMENT";
+ /**
+ * The provided attestation for the minimum age couldn't be verified by the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_DEPOSIT_COIN_AGE_ATTESTATION_FAILURE"] = 1030] = "EXCHANGE_PURSE_DEPOSIT_COIN_AGE_ATTESTATION_FAILURE";
+ /**
+ * The exchange did not find information about the specified transaction in the database.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_NOT_FOUND"] = 1100] = "EXCHANGE_DEPOSITS_GET_NOT_FOUND";
+ /**
+ * The wire hash of given to a "/deposits/" handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE"] = 1101] = "EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE";
+ /**
+ * The merchant key of given to a "/deposits/" handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB"] = 1102] = "EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB";
+ /**
+ * The hash of the contract terms given to a "/deposits/" handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS"] = 1103] = "EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS";
+ /**
+ * The coin public key of given to a "/deposits/" handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB"] = 1104] = "EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB";
+ /**
+ * The signature returned by the exchange in a /deposits/ request was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE"] = 1105] = "EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE";
+ /**
+ * The signature of the merchant is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID"] = 1106] = "EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID";
+ /**
+ * The provided policy data was not accepted
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED"] = 1107] = "EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED";
+ /**
+ * The given reserve does not have sufficient funds to admit the requested withdraw operation at this time. The response includes the current "balance" of the reserve as well as the transaction "history" that lead to this balance.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS"] = 1150] = "EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS";
+ /**
+ * The amount to withdraw together with the fee exceeds the numeric range for Taler amounts. This is not a client failure, as the coin value and fees come from the exchange's configuration.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW"] = 1152] = "EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW";
+ /**
+ * The exchange failed to create the signature using the denomination key.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_SIGNATURE_FAILED"] = 1153] = "EXCHANGE_WITHDRAW_SIGNATURE_FAILED";
+ /**
+ * The signature of the reserve is not valid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID"] = 1154] = "EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID";
+ /**
+ * When computing the reserve history, we ended up with a negative overall balance, which should be impossible.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS"] = 1155] = "EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS";
+ /**
+ * Withdraw period of the coin to be withdrawn is in the past.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_DENOMINATION_KEY_LOST"] = 1158] = "EXCHANGE_WITHDRAW_DENOMINATION_KEY_LOST";
+ /**
+ * The client failed to unblind the blind signature.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_UNBLIND_FAILURE"] = 1159] = "EXCHANGE_WITHDRAW_UNBLIND_FAILURE";
+ /**
+ * The client re-used a withdraw nonce, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_NONCE_REUSE"] = 1160] = "EXCHANGE_WITHDRAW_NONCE_REUSE";
+ /**
+ * The batch withdraw included a planchet that was already withdrawn. This is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WITHDRAW_BATCH_IDEMPOTENT_PLANCHET"] = 1175] = "EXCHANGE_WITHDRAW_BATCH_IDEMPOTENT_PLANCHET";
+ /**
+ * The signature made by the coin over the deposit permission is not valid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID"] = 1205] = "EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID";
+ /**
+ * The same coin was already deposited for the same merchant and contract with other details.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT"] = 1206] = "EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT";
+ /**
+ * The stated value of the coin after the deposit fee is subtracted would be negative.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE"] = 1207] = "EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE";
+ /**
+ * The stated refund deadline is after the wire deadline.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE"] = 1208] = "EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE";
+ /**
+ * The stated wire deadline is "never", which makes no sense.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER"] = 1209] = "EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER";
+ /**
+ * The exchange failed to canonicalize and hash the given wire format. For example, the merchant failed to provide the "salt" or a valid payto:// URI in the wire details. Note that while the exchange will do some basic sanity checking on the wire details, it cannot warrant that the banking system will ultimately be able to route to the specified address, even if this check passed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON"] = 1210] = "EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON";
+ /**
+ * The hash of the given wire address does not match the wire hash specified in the proposal data.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT"] = 1211] = "EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT";
+ /**
+ * The signature provided by the exchange is not valid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE"] = 1221] = "EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE";
+ /**
+ * The deposited amount is smaller than the deposit fee, which would result in a negative contribution.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT"] = 1222] = "EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT";
+ /**
+ * The proof of policy fulfillment was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_EXTENSIONS_INVALID_FULFILLMENT"] = 1240] = "EXCHANGE_EXTENSIONS_INVALID_FULFILLMENT";
+ /**
+ * The reserve balance, status or history was requested for a reserve which is not known to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_STATUS_UNKNOWN"] = 1250] = "EXCHANGE_RESERVES_STATUS_UNKNOWN";
+ /**
+ * The reserve status was requested with a bad signature.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_STATUS_BAD_SIGNATURE"] = 1251] = "EXCHANGE_RESERVES_STATUS_BAD_SIGNATURE";
+ /**
+ * The reserve history was requested with a bad signature.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_HISTORY_BAD_SIGNATURE"] = 1252] = "EXCHANGE_RESERVES_HISTORY_BAD_SIGNATURE";
+ /**
+ * The exchange encountered melt fees exceeding the melted coin's contribution.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION"] = 1302] = "EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION";
+ /**
+ * The signature made with the coin to be melted is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_COIN_SIGNATURE_INVALID"] = 1303] = "EXCHANGE_MELT_COIN_SIGNATURE_INVALID";
+ /**
+ * The denomination of the given coin has past its expiration date and it is also not a valid zombie (that is, was not refreshed with the fresh coin being subjected to recoup).
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE"] = 1305] = "EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE";
+ /**
+ * The signature returned by the exchange in a melt request was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE"] = 1306] = "EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE";
+ /**
+ * The provided transfer keys do not match up with the original commitment. Information about the original commitment is included in the response.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_COMMITMENT_VIOLATION"] = 1353] = "EXCHANGE_REFRESHES_REVEAL_COMMITMENT_VIOLATION";
+ /**
+ * Failed to produce the blinded signatures over the coins to be returned.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_SIGNING_ERROR"] = 1354] = "EXCHANGE_REFRESHES_REVEAL_SIGNING_ERROR";
+ /**
+ * The exchange is unaware of the refresh session specified in the request.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_SESSION_UNKNOWN"] = 1355] = "EXCHANGE_REFRESHES_REVEAL_SESSION_UNKNOWN";
+ /**
+ * The size of the cut-and-choose dimension of the private transfer keys request does not match #TALER_CNC_KAPPA - 1.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID"] = 1356] = "EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID";
+ /**
+ * The number of envelopes given does not match the number of denomination keys given.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH"] = 1358] = "EXCHANGE_REFRESHES_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH";
+ /**
+ * The exchange encountered a numeric overflow totaling up the cost for the refresh operation.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_COST_CALCULATION_OVERFLOW"] = 1359] = "EXCHANGE_REFRESHES_REVEAL_COST_CALCULATION_OVERFLOW";
+ /**
+ * The exchange's cost calculation shows that the melt amount is below the costs of the transaction.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AMOUNT_INSUFFICIENT"] = 1360] = "EXCHANGE_REFRESHES_REVEAL_AMOUNT_INSUFFICIENT";
+ /**
+ * The signature made with the coin over the link data is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID"] = 1361] = "EXCHANGE_REFRESHES_REVEAL_LINK_SIGNATURE_INVALID";
+ /**
+ * The refresh session hash given to a /refreshes/ handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_INVALID_RCH"] = 1362] = "EXCHANGE_REFRESHES_REVEAL_INVALID_RCH";
+ /**
+ * Operation specified invalid for this endpoint.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID"] = 1363] = "EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID";
+ /**
+ * The client provided age commitment data, but age restriction is not supported on this server.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_NOT_SUPPORTED"] = 1364] = "EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_NOT_SUPPORTED";
+ /**
+ * The client provided invalid age commitment data: missing, not an array, or array of invalid size.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID"] = 1365] = "EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID";
+ /**
+ * The coin specified in the link request is unknown to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_LINK_COIN_UNKNOWN"] = 1400] = "EXCHANGE_LINK_COIN_UNKNOWN";
+ /**
+ * The public key of given to a /transfers/ handler was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WTID_MALFORMED"] = 1450] = "EXCHANGE_TRANSFERS_GET_WTID_MALFORMED";
+ /**
+ * The exchange did not find information about the specified wire transfer identifier in the database.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WTID_NOT_FOUND"] = 1451] = "EXCHANGE_TRANSFERS_GET_WTID_NOT_FOUND";
+ /**
+ * The exchange did not find information about the wire transfer fees it charged.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WIRE_FEE_NOT_FOUND"] = 1452] = "EXCHANGE_TRANSFERS_GET_WIRE_FEE_NOT_FOUND";
+ /**
+ * The exchange found a wire fee that was above the total transfer value (and thus could not have been charged).
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_TRANSFERS_GET_WIRE_FEE_INCONSISTENT"] = 1453] = "EXCHANGE_TRANSFERS_GET_WIRE_FEE_INCONSISTENT";
+ /**
+ * The wait target of the URL was not in the set of expected values.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSES_INVALID_WAIT_TARGET"] = 1475] = "EXCHANGE_PURSES_INVALID_WAIT_TARGET";
+ /**
+ * The signature on the purse status returned by the exchange was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSES_GET_INVALID_SIGNATURE_BY_EXCHANGE"] = 1476] = "EXCHANGE_PURSES_GET_INVALID_SIGNATURE_BY_EXCHANGE";
+ /**
+ * The exchange knows literally nothing about the coin we were asked to refund. But without a transaction history, we cannot issue a refund. This is kind-of OK, the owner should just refresh it directly without executing the refund.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_COIN_NOT_FOUND"] = 1500] = "EXCHANGE_REFUND_COIN_NOT_FOUND";
+ /**
+ * We could not process the refund request as the coin's transaction history does not permit the requested refund because then refunds would exceed the deposit amount. The "history" in the response proves this.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_CONFLICT_DEPOSIT_INSUFFICIENT"] = 1501] = "EXCHANGE_REFUND_CONFLICT_DEPOSIT_INSUFFICIENT";
+ /**
+ * The exchange knows about the coin we were asked to refund, but not about the specific /deposit operation. Hence, we cannot issue a refund (as we do not know if this merchant public key is authorized to do a refund).
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_DEPOSIT_NOT_FOUND"] = 1502] = "EXCHANGE_REFUND_DEPOSIT_NOT_FOUND";
+ /**
+ * The exchange can no longer refund the customer/coin as the money was already transferred (paid out) to the merchant. (It should be past the refund deadline.)
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_ALREADY_PAID"] = 1503] = "EXCHANGE_REFUND_MERCHANT_ALREADY_PAID";
+ /**
+ * The refund fee specified for the request is lower than the refund fee charged by the exchange for the given denomination key of the refunded coin.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_FEE_TOO_LOW"] = 1504] = "EXCHANGE_REFUND_FEE_TOO_LOW";
+ /**
+ * The refunded amount is smaller than the refund fee, which would result in a negative refund.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_FEE_ABOVE_AMOUNT"] = 1505] = "EXCHANGE_REFUND_FEE_ABOVE_AMOUNT";
+ /**
+ * The signature of the merchant is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID"] = 1506] = "EXCHANGE_REFUND_MERCHANT_SIGNATURE_INVALID";
+ /**
+ * Merchant backend failed to create the refund confirmation signature.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_MERCHANT_SIGNING_FAILED"] = 1507] = "EXCHANGE_REFUND_MERCHANT_SIGNING_FAILED";
+ /**
+ * The signature returned by the exchange in a refund request was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE"] = 1508] = "EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE";
+ /**
+ * The failure proof returned by the exchange is incorrect.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE"] = 1509] = "EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE";
+ /**
+ * Conflicting refund granted before with different amount but same refund transaction ID.
+ * Returned with an HTTP status code of #MHD_HTTP_FAILED_DEPENDENCY (424).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_REFUND_INCONSISTENT_AMOUNT"] = 1510] = "EXCHANGE_REFUND_INCONSISTENT_AMOUNT";
+ /**
+ * The given coin signature is invalid for the request.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_SIGNATURE_INVALID"] = 1550] = "EXCHANGE_RECOUP_SIGNATURE_INVALID";
+ /**
+ * The exchange could not find the corresponding withdraw operation. The request is denied.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_WITHDRAW_NOT_FOUND"] = 1551] = "EXCHANGE_RECOUP_WITHDRAW_NOT_FOUND";
+ /**
+ * The coin's remaining balance is zero. The request is denied.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_COIN_BALANCE_ZERO"] = 1552] = "EXCHANGE_RECOUP_COIN_BALANCE_ZERO";
+ /**
+ * The exchange failed to reproduce the coin's blinding.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_BLINDING_FAILED"] = 1553] = "EXCHANGE_RECOUP_BLINDING_FAILED";
+ /**
+ * The coin's remaining balance is zero. The request is denied.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_COIN_BALANCE_NEGATIVE"] = 1554] = "EXCHANGE_RECOUP_COIN_BALANCE_NEGATIVE";
+ /**
+ * The coin's denomination has not been revoked yet.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_NOT_ELIGIBLE"] = 1555] = "EXCHANGE_RECOUP_NOT_ELIGIBLE";
+ /**
+ * The given coin signature is invalid for the request.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_SIGNATURE_INVALID"] = 1575] = "EXCHANGE_RECOUP_REFRESH_SIGNATURE_INVALID";
+ /**
+ * The exchange could not find the corresponding melt operation. The request is denied.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_MELT_NOT_FOUND"] = 1576] = "EXCHANGE_RECOUP_REFRESH_MELT_NOT_FOUND";
+ /**
+ * The exchange failed to reproduce the coin's blinding.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED"] = 1578] = "EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED";
+ /**
+ * The coin's denomination has not been revoked yet.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RECOUP_REFRESH_NOT_ELIGIBLE"] = 1580] = "EXCHANGE_RECOUP_REFRESH_NOT_ELIGIBLE";
+ /**
+ * This exchange does not allow clients to request /keys for times other than the current (exchange) time.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KEYS_TIMETRAVEL_FORBIDDEN"] = 1600] = "EXCHANGE_KEYS_TIMETRAVEL_FORBIDDEN";
+ /**
+ * A signature in the server's response was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_SIGNATURE_INVALID"] = 1650] = "EXCHANGE_WIRE_SIGNATURE_INVALID";
+ /**
+ * No bank accounts are enabled for the exchange. The administrator should enable-account using the taler-exchange-offline tool.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED"] = 1651] = "EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED";
+ /**
+ * The payto:// URI stored in the exchange database for its bank account is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED"] = 1652] = "EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED";
+ /**
+ * No wire fees are configured for an enabled wire method of the exchange. The administrator must set the wire-fee using the taler-exchange-offline tool.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_WIRE_FEES_NOT_CONFIGURED"] = 1653] = "EXCHANGE_WIRE_FEES_NOT_CONFIGURED";
+ /**
+ * This purse was previously created with different meta data.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_CREATE_CONFLICTING_META_DATA"] = 1675] = "EXCHANGE_RESERVES_PURSE_CREATE_CONFLICTING_META_DATA";
+ /**
+ * This purse was previously merged with different meta data.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_MERGE_CONFLICTING_META_DATA"] = 1676] = "EXCHANGE_RESERVES_PURSE_MERGE_CONFLICTING_META_DATA";
+ /**
+ * The reserve has insufficient funds to create another purse.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_CREATE_INSUFFICIENT_FUNDS"] = 1677] = "EXCHANGE_RESERVES_PURSE_CREATE_INSUFFICIENT_FUNDS";
+ /**
+ * The purse fee specified for the request is lower than the purse fee charged by the exchange at this time.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_FEE_TOO_LOW"] = 1678] = "EXCHANGE_RESERVES_PURSE_FEE_TOO_LOW";
+ /**
+ * The exchange failed to talk to the process responsible for its private denomination keys.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE"] = 1700] = "EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE";
+ /**
+ * The response from the denomination key helper process was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_BUG"] = 1701] = "EXCHANGE_DENOMINATION_HELPER_BUG";
+ /**
+ * The helper refuses to sign with the key, because it is too early: the validity period has not yet started.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_DENOMINATION_HELPER_TOO_EARLY"] = 1702] = "EXCHANGE_DENOMINATION_HELPER_TOO_EARLY";
+ /**
+ * The signature of the exchange on the reply was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_DEPOSIT_EXCHANGE_SIGNATURE_INVALID"] = 1725] = "EXCHANGE_PURSE_DEPOSIT_EXCHANGE_SIGNATURE_INVALID";
+ /**
+ * The exchange failed to talk to the process responsible for its private signing keys.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE"] = 1750] = "EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE";
+ /**
+ * The response from the online signing key helper process was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_BUG"] = 1751] = "EXCHANGE_SIGNKEY_HELPER_BUG";
+ /**
+ * The helper refuses to sign with the key, because it is too early: the validity period has not yet started.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_SIGNKEY_HELPER_TOO_EARLY"] = 1752] = "EXCHANGE_SIGNKEY_HELPER_TOO_EARLY";
+ /**
+ * The purse expiration time is in the past at the time of its creation.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_EXPIRATION_BEFORE_NOW"] = 1775] = "EXCHANGE_RESERVES_PURSE_EXPIRATION_BEFORE_NOW";
+ /**
+ * The purse expiration time is set to never, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_EXPIRATION_IS_NEVER"] = 1776] = "EXCHANGE_RESERVES_PURSE_EXPIRATION_IS_NEVER";
+ /**
+ * The signature affirming the merge of the purse is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_PURSE_MERGE_SIGNATURE_INVALID"] = 1777] = "EXCHANGE_RESERVES_PURSE_MERGE_SIGNATURE_INVALID";
+ /**
+ * The signature by the reserve affirming the merge is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_RESERVE_MERGE_SIGNATURE_INVALID"] = 1778] = "EXCHANGE_RESERVES_RESERVE_MERGE_SIGNATURE_INVALID";
+ /**
+ * The signature by the reserve affirming the open operation is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_OPEN_BAD_SIGNATURE"] = 1785] = "EXCHANGE_RESERVES_OPEN_BAD_SIGNATURE";
+ /**
+ * The signature by the reserve affirming the close operation is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_CLOSE_BAD_SIGNATURE"] = 1786] = "EXCHANGE_RESERVES_CLOSE_BAD_SIGNATURE";
+ /**
+ * The signature by the reserve affirming the attestion request is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_ATTEST_BAD_SIGNATURE"] = 1787] = "EXCHANGE_RESERVES_ATTEST_BAD_SIGNATURE";
+ /**
+ * The exchange does not know an origin account to which the remaining reserve balance could be wired to, and the wallet failed to provide one.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_RESERVES_CLOSE_NO_TARGET_ACCOUNT"] = 1788] = "EXCHANGE_RESERVES_CLOSE_NO_TARGET_ACCOUNT";
+ /**
+ * The auditor that was supposed to be disabled is unknown to this exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_NOT_FOUND"] = 1800] = "EXCHANGE_MANAGEMENT_AUDITOR_NOT_FOUND";
+ /**
+ * The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected).
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_MORE_RECENT_PRESENT"] = 1801] = "EXCHANGE_MANAGEMENT_AUDITOR_MORE_RECENT_PRESENT";
+ /**
+ * The signature to add or enable the auditor does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID"] = 1802] = "EXCHANGE_MANAGEMENT_AUDITOR_ADD_SIGNATURE_INVALID";
+ /**
+ * The signature to disable the auditor does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID"] = 1803] = "EXCHANGE_MANAGEMENT_AUDITOR_DEL_SIGNATURE_INVALID";
+ /**
+ * The signature to revoke the denomination does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID"] = 1804] = "EXCHANGE_MANAGEMENT_DENOMINATION_REVOKE_SIGNATURE_INVALID";
+ /**
+ * The signature to revoke the online signing key does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID"] = 1805] = "EXCHANGE_MANAGEMENT_SIGNKEY_REVOKE_SIGNATURE_INVALID";
+ /**
+ * The exchange has a more recently signed conflicting instruction and is thus refusing the current change (replay detected).
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_MORE_RECENT_PRESENT"] = 1806] = "EXCHANGE_MANAGEMENT_WIRE_MORE_RECENT_PRESENT";
+ /**
+ * The signingkey specified is unknown to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN"] = 1807] = "EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN";
+ /**
+ * The signature to publish wire account does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_DETAILS_SIGNATURE_INVALID"] = 1808] = "EXCHANGE_MANAGEMENT_WIRE_DETAILS_SIGNATURE_INVALID";
+ /**
+ * The signature to add the wire account does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID"] = 1809] = "EXCHANGE_MANAGEMENT_WIRE_ADD_SIGNATURE_INVALID";
+ /**
+ * The signature to disable the wire account does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID"] = 1810] = "EXCHANGE_MANAGEMENT_WIRE_DEL_SIGNATURE_INVALID";
+ /**
+ * The wire account to be disabled is unknown to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_NOT_FOUND"] = 1811] = "EXCHANGE_MANAGEMENT_WIRE_NOT_FOUND";
+ /**
+ * The signature to affirm wire fees does not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID"] = 1812] = "EXCHANGE_MANAGEMENT_WIRE_FEE_SIGNATURE_INVALID";
+ /**
+ * The signature conflicts with a previous signature affirming different fees.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_WIRE_FEE_MISMATCH"] = 1813] = "EXCHANGE_MANAGEMENT_WIRE_FEE_MISMATCH";
+ /**
+ * The signature affirming the denomination key is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID"] = 1814] = "EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID";
+ /**
+ * The signature affirming the signing key is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID"] = 1815] = "EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID";
+ /**
+ * The signature conflicts with a previous signature affirming different fees.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_GLOBAL_FEE_MISMATCH"] = 1816] = "EXCHANGE_MANAGEMENT_GLOBAL_FEE_MISMATCH";
+ /**
+ * The signature affirming the fee structure is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_GLOBAL_FEE_SIGNATURE_INVALID"] = 1817] = "EXCHANGE_MANAGEMENT_GLOBAL_FEE_SIGNATURE_INVALID";
+ /**
+ * The signature affirming the profit drain is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MANAGEMENT_DRAIN_PROFITS_SIGNATURE_INVALID"] = 1818] = "EXCHANGE_MANAGEMENT_DRAIN_PROFITS_SIGNATURE_INVALID";
+ /**
+ * The purse was previously created with different meta data.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA"] = 1850] = "EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA";
+ /**
+ * The purse was previously created with a different contract.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_CONFLICTING_CONTRACT_STORED"] = 1851] = "EXCHANGE_PURSE_CREATE_CONFLICTING_CONTRACT_STORED";
+ /**
+ * A coin signature for a deposit into the purse is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID"] = 1852] = "EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID";
+ /**
+ * The purse expiration time is in the past.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_EXPIRATION_BEFORE_NOW"] = 1853] = "EXCHANGE_PURSE_CREATE_EXPIRATION_BEFORE_NOW";
+ /**
+ * The purse expiration time is "never".
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_EXPIRATION_IS_NEVER"] = 1854] = "EXCHANGE_PURSE_CREATE_EXPIRATION_IS_NEVER";
+ /**
+ * The purse signature over the purse meta data is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID"] = 1855] = "EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID";
+ /**
+ * The signature over the encrypted contract is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_ECONTRACT_SIGNATURE_INVALID"] = 1856] = "EXCHANGE_PURSE_ECONTRACT_SIGNATURE_INVALID";
+ /**
+ * The signature from the exchange over the confirmation is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_CREATE_EXCHANGE_SIGNATURE_INVALID"] = 1857] = "EXCHANGE_PURSE_CREATE_EXCHANGE_SIGNATURE_INVALID";
+ /**
+ * The coin was previously deposited with different meta data.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA"] = 1858] = "EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA";
+ /**
+ * The encrypted contract was previously uploaded with different meta data.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA"] = 1859] = "EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA";
+ /**
+ * The deposited amount is less than the purse fee.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CREATE_PURSE_NEGATIVE_VALUE_AFTER_FEE"] = 1860] = "EXCHANGE_CREATE_PURSE_NEGATIVE_VALUE_AFTER_FEE";
+ /**
+ * The signature using the merge key is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_MERGE_INVALID_MERGE_SIGNATURE"] = 1876] = "EXCHANGE_PURSE_MERGE_INVALID_MERGE_SIGNATURE";
+ /**
+ * The signature using the reserve key is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_MERGE_INVALID_RESERVE_SIGNATURE"] = 1877] = "EXCHANGE_PURSE_MERGE_INVALID_RESERVE_SIGNATURE";
+ /**
+ * The targeted purse is not yet full and thus cannot be merged. Retrying the request later may succeed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_NOT_FULL"] = 1878] = "EXCHANGE_PURSE_NOT_FULL";
+ /**
+ * The signature from the exchange over the confirmation is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_MERGE_EXCHANGE_SIGNATURE_INVALID"] = 1879] = "EXCHANGE_PURSE_MERGE_EXCHANGE_SIGNATURE_INVALID";
+ /**
+ * The exchange of the target account is not a partner of this exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_MERGE_PURSE_PARTNER_UNKNOWN"] = 1880] = "EXCHANGE_MERGE_PURSE_PARTNER_UNKNOWN";
+ /**
+ * The auditor signature over the denomination meta data is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_SIGNATURE_INVALID"] = 1900] = "EXCHANGE_AUDITORS_AUDITOR_SIGNATURE_INVALID";
+ /**
+ * The auditor that was specified is unknown to this exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_UNKNOWN"] = 1901] = "EXCHANGE_AUDITORS_AUDITOR_UNKNOWN";
+ /**
+ * The auditor that was specified is no longer used by this exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_AUDITORS_AUDITOR_INACTIVE"] = 1902] = "EXCHANGE_AUDITORS_AUDITOR_INACTIVE";
+ /**
+ * The signature affirming the wallet's KYC request was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_WALLET_SIGNATURE_INVALID"] = 1925] = "EXCHANGE_KYC_WALLET_SIGNATURE_INVALID";
+ /**
+ * The exchange received an unexpected malformed response from its KYC backend.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE"] = 1926] = "EXCHANGE_KYC_PROOF_BACKEND_INVALID_RESPONSE";
+ /**
+ * The backend signaled an unexpected failure.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_ERROR"] = 1927] = "EXCHANGE_KYC_PROOF_BACKEND_ERROR";
+ /**
+ * The backend signaled an authorization failure.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_BACKEND_AUTHORIZATION_FAILED"] = 1928] = "EXCHANGE_KYC_PROOF_BACKEND_AUTHORIZATION_FAILED";
+ /**
+ * The exchange is unaware of having made an the authorization request.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_PROOF_REQUEST_UNKNOWN"] = 1929] = "EXCHANGE_KYC_PROOF_REQUEST_UNKNOWN";
+ /**
+ * The payto-URI hash did not match. Hence the request was denied.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED"] = 1930] = "EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED";
+ /**
+ * The request used a logic specifier that is not known to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN"] = 1931] = "EXCHANGE_KYC_GENERIC_LOGIC_UNKNOWN";
+ /**
+ * The request requires a logic which is no longer configured at the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_LOGIC_GONE"] = 1932] = "EXCHANGE_KYC_GENERIC_LOGIC_GONE";
+ /**
+ * The logic plugin had a bug in its interaction with the KYC provider.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_LOGIC_BUG"] = 1933] = "EXCHANGE_KYC_GENERIC_LOGIC_BUG";
+ /**
+ * The exchange could not process the request with its KYC provider because the provider refused access to the service. This indicates some configuration issue at the Taler exchange operator.
+ * Returned with an HTTP status code of #MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED (511).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_PROVIDER_ACCESS_REFUSED"] = 1934] = "EXCHANGE_KYC_GENERIC_PROVIDER_ACCESS_REFUSED";
+ /**
+ * There was a timeout in the interaction between the exchange and the KYC provider. The most likely cause is some networking problem. Trying again later might succeed.
+ * Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_PROVIDER_TIMEOUT"] = 1935] = "EXCHANGE_KYC_GENERIC_PROVIDER_TIMEOUT";
+ /**
+ * The KYC provider responded with a status that was completely unexpected by the KYC logic of the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_PROVIDER_UNEXPECTED_REPLY"] = 1936] = "EXCHANGE_KYC_GENERIC_PROVIDER_UNEXPECTED_REPLY";
+ /**
+ * The rate limit of the exchange at the KYC provider has been exceeded. Trying much later might work.
+ * Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_GENERIC_PROVIDER_RATE_LIMIT_EXCEEDED"] = 1937] = "EXCHANGE_KYC_GENERIC_PROVIDER_RATE_LIMIT_EXCEEDED";
+ /**
+ * The request to the webhook lacked proper authorization or authentication data.
+ * Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_KYC_WEBHOOK_UNAUTHORIZED"] = 1938] = "EXCHANGE_KYC_WEBHOOK_UNAUTHORIZED";
+ /**
+ * The exchange does not know a contract under the given contract public key.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CONTRACTS_UNKNOWN"] = 1950] = "EXCHANGE_CONTRACTS_UNKNOWN";
+ /**
+ * The URL does not encode a valid exchange public key in its path.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CONTRACTS_INVALID_CONTRACT_PUB"] = 1951] = "EXCHANGE_CONTRACTS_INVALID_CONTRACT_PUB";
+ /**
+ * The returned encrypted contract did not decrypt.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CONTRACTS_DECRYPTION_FAILED"] = 1952] = "EXCHANGE_CONTRACTS_DECRYPTION_FAILED";
+ /**
+ * The signature on the encrypted contract did not validate.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CONTRACTS_SIGNATURE_INVALID"] = 1953] = "EXCHANGE_CONTRACTS_SIGNATURE_INVALID";
+ /**
+ * The decrypted contract was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_CONTRACTS_DECODING_FAILED"] = 1954] = "EXCHANGE_CONTRACTS_DECODING_FAILED";
+ /**
+ * A coin signature for a deposit into the purse is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID"] = 1975] = "EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID";
+ /**
+ * The backend could not find the merchant instance specified in the request.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_INSTANCE_UNKNOWN"] = 2000] = "MERCHANT_GENERIC_INSTANCE_UNKNOWN";
+ /**
+ * The start and end-times in the wire fee structure leave a hole. This is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_HOLE_IN_WIRE_FEE_STRUCTURE"] = 2001] = "MERCHANT_GENERIC_HOLE_IN_WIRE_FEE_STRUCTURE";
+ /**
+ * The proposal is not known to the backend.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_ORDER_UNKNOWN"] = 2005] = "MERCHANT_GENERIC_ORDER_UNKNOWN";
+ /**
+ * The order provided to the backend could not be completed, because a product to be completed via inventory data is not actually in our inventory.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_PRODUCT_UNKNOWN"] = 2006] = "MERCHANT_GENERIC_PRODUCT_UNKNOWN";
+ /**
+ * The tip ID is unknown. This could happen if the tip has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_TIP_ID_UNKNOWN"] = 2007] = "MERCHANT_GENERIC_TIP_ID_UNKNOWN";
+ /**
+ * The contract obtained from the merchant backend was malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID"] = 2008] = "MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID";
+ /**
+ * The order we found does not match the provided contract hash.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER"] = 2009] = "MERCHANT_GENERIC_CONTRACT_HASH_DOES_NOT_MATCH_ORDER";
+ /**
+ * The exchange failed to provide a valid response to the merchant's /keys request.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE"] = 2010] = "MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE";
+ /**
+ * The exchange failed to respond to the merchant on time.
+ * Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_TIMEOUT"] = 2011] = "MERCHANT_GENERIC_EXCHANGE_TIMEOUT";
+ /**
+ * The merchant failed to talk to the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE"] = 2012] = "MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE";
+ /**
+ * The exchange returned a maformed response.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED"] = 2013] = "MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED";
+ /**
+ * The exchange returned an unexpected response status.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS"] = 2014] = "MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS";
+ /**
+ * The merchant refused the request due to lack of authorization.
+ * Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_UNAUTHORIZED"] = 2015] = "MERCHANT_GENERIC_UNAUTHORIZED";
+ /**
+ * The merchant instance specified in the request was deleted.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_INSTANCE_DELETED"] = 2016] = "MERCHANT_GENERIC_INSTANCE_DELETED";
+ /**
+ * The backend could not find the inbound wire transfer specified in the request.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GENERIC_TRANSFER_UNKNOWN"] = 2017] = "MERCHANT_GENERIC_TRANSFER_UNKNOWN";
+ /**
+ * The exchange failed to provide a valid answer to the tracking request, thus those details are not in the response.
+ * Returned with an HTTP status code of #MHD_HTTP_OK (200).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_EXCHANGE_TRACKING_FAILURE"] = 2100] = "MERCHANT_GET_ORDERS_EXCHANGE_TRACKING_FAILURE";
+ /**
+ * The merchant backend failed to construct the request for tracking to the exchange, thus tracking details are not in the response.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_EXCHANGE_REQUEST_FAILURE"] = 2103] = "MERCHANT_GET_ORDERS_ID_EXCHANGE_REQUEST_FAILURE";
+ /**
+ * The merchant backend failed trying to contact the exchange for tracking details, thus those details are not in the response.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_EXCHANGE_LOOKUP_START_FAILURE"] = 2104] = "MERCHANT_GET_ORDERS_ID_EXCHANGE_LOOKUP_START_FAILURE";
+ /**
+ * The claim token used to authenticate the client is invalid for this order.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_INVALID_TOKEN"] = 2105] = "MERCHANT_GET_ORDERS_ID_INVALID_TOKEN";
+ /**
+ * The contract terms hash used to authenticate the client is invalid for this order.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_GET_ORDERS_ID_INVALID_CONTRACT_HASH"] = 2106] = "MERCHANT_GET_ORDERS_ID_INVALID_CONTRACT_HASH";
+ /**
+ * The exchange responded saying that funds were insufficient (for example, due to double-spending).
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS"] = 2150] = "MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS";
+ /**
+ * The denomination key used for payment is not listed among the denomination keys of the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND"] = 2151] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND";
+ /**
+ * The denomination key used for payment is not audited by an auditor approved by the merchant.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_AUDITOR_FAILURE"] = 2152] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_AUDITOR_FAILURE";
+ /**
+ * There was an integer overflow totaling up the amounts or deposit fees in the payment.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW"] = 2153] = "MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW";
+ /**
+ * The deposit fees exceed the total value of the payment.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT"] = 2154] = "MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT";
+ /**
+ * After considering deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract. The client should revisit the logic used to calculate fees it must cover.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES"] = 2155] = "MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES";
+ /**
+ * Even if we do not consider deposit and wire fees, the payment is insufficient to satisfy the required amount for the contract.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_ACCEPTABLE (406).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT"] = 2156] = "MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT";
+ /**
+ * The signature over the contract of one of the coins was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_COIN_SIGNATURE_INVALID"] = 2157] = "MERCHANT_POST_ORDERS_ID_PAY_COIN_SIGNATURE_INVALID";
+ /**
+ * When we tried to find information about the exchange to issue the deposit, we failed. This usually only happens if the merchant backend is somehow unable to get its own HTTP client logic to work.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED"] = 2158] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LOOKUP_FAILED";
+ /**
+ * The refund deadline in the contract is after the transfer deadline.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE"] = 2159] = "MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE";
+ /**
+ * The order was already paid (maybe by another wallet).
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID"] = 2160] = "MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID";
+ /**
+ * The payment is too late, the offer has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED"] = 2161] = "MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED";
+ /**
+ * The "merchant" field is missing in the proposal data. This is an internal error as the proposal is from the merchant's own database at this point.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING"] = 2162] = "MERCHANT_POST_ORDERS_ID_PAY_MERCHANT_FIELD_MISSING";
+ /**
+ * Failed to locate merchant's account information matching the wire hash given in the proposal.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN"] = 2163] = "MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN";
+ /**
+ * The deposit time for the denomination has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED"] = 2165] = "MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED";
+ /**
+ * The exchange of the deposited coin charges a wire fee that could not be added to the total (total amount too high).
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED"] = 2166] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED";
+ /**
+ * The contract was not fully paid because of refunds. Note that clients MAY treat this as paid if, for example, contracts must be executed despite of refunds.
+ * Returned with an HTTP status code of #MHD_HTTP_PAYMENT_REQUIRED (402).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUNDED"] = 2167] = "MERCHANT_POST_ORDERS_ID_PAY_REFUNDED";
+ /**
+ * According to our database, we have refunded more than we were paid (which should not be possible).
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS"] = 2168] = "MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS";
+ /**
+ * Legacy stuff. Remove me with protocol v1.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["DEAD_QQQ_PAY_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE"] = 2169] = "DEAD_QQQ_PAY_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE";
+ /**
+ * The payment failed at the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_FAILED"] = 2170] = "MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_FAILED";
+ /**
+ * The payment required a minimum age but one of the coins (of a denomination with support for age restriction) did not provide any age_commitment.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_MISSING"] = 2171] = "MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_MISSING";
+ /**
+ * The payment required a minimum age but one of the coins provided an age_commitment that contained a wrong number of public keys compared to the number of age groups defined in the denomination of the coin.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_SIZE_MISMATCH"] = 2172] = "MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_SIZE_MISMATCH";
+ /**
+ * The payment required a minimum age but one of the coins provided a minimum_age_sig that couldn't be verified with the given age_commitment for that particular minimum age.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED"] = 2173] = "MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED";
+ /**
+ * The payment required no minimum age but one of the coins (of a denomination with support for age restriction) did not provide the required h_age_commitment.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_HASH_MISSING"] = 2174] = "MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_HASH_MISSING";
+ /**
+ * The contract hash does not match the given order ID.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH"] = 2200] = "MERCHANT_POST_ORDERS_ID_PAID_CONTRACT_HASH_MISMATCH";
+ /**
+ * The signature of the merchant is not valid for the given contract hash.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID"] = 2201] = "MERCHANT_POST_ORDERS_ID_PAID_COIN_SIGNATURE_INVALID";
+ /**
+ * The merchant failed to send the exchange the refund request.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED"] = 2251] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_REFUND_FAILED";
+ /**
+ * The merchant failed to find the exchange to process the lookup.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED"] = 2252] = "MERCHANT_POST_ORDERS_ID_ABORT_EXCHANGE_LOOKUP_FAILED";
+ /**
+ * The merchant could not find the contract.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND"] = 2253] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND";
+ /**
+ * The payment was already completed and thus cannot be aborted anymore.
+ * Returned with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED (412).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE"] = 2254] = "MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE";
+ /**
+ * The hash provided by the wallet does not match the order.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH"] = 2255] = "MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH";
+ /**
+ * The array of coins cannot be empty.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY"] = 2256] = "MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY";
+ /**
+ * We could not claim the order because the backend is unaware of it.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND"] = 2300] = "MERCHANT_POST_ORDERS_ID_CLAIM_NOT_FOUND";
+ /**
+ * We could not claim the order because someone else claimed it first.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED"] = 2301] = "MERCHANT_POST_ORDERS_ID_CLAIM_ALREADY_CLAIMED";
+ /**
+ * The client-side experienced an internal failure.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE"] = 2302] = "MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE";
+ /**
+ * The backend failed to sign the refund request.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_POST_ORDERS_ID_REFUND_SIGNATURE_FAILED"] = 2350] = "MERCHANT_POST_ORDERS_ID_REFUND_SIGNATURE_FAILED";
+ /**
+ * The client failed to unblind the signature returned by the merchant.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_UNBLIND_FAILURE"] = 2400] = "MERCHANT_TIP_PICKUP_UNBLIND_FAILURE";
+ /**
+ * The exchange returned a failure code for the withdraw operation.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_EXCHANGE_ERROR"] = 2403] = "MERCHANT_TIP_PICKUP_EXCHANGE_ERROR";
+ /**
+ * The merchant failed to add up the amounts to compute the pick up value.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_SUMMATION_FAILED"] = 2404] = "MERCHANT_TIP_PICKUP_SUMMATION_FAILED";
+ /**
+ * The tip expired.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_HAS_EXPIRED"] = 2405] = "MERCHANT_TIP_PICKUP_HAS_EXPIRED";
+ /**
+ * The requested withdraw amount exceeds the amount remaining to be picked up.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING"] = 2406] = "MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING";
+ /**
+ * The merchant did not find the specified denomination key in the exchange's key set.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_TIP_PICKUP_DENOMINATION_UNKNOWN"] = 2407] = "MERCHANT_TIP_PICKUP_DENOMINATION_UNKNOWN";
+ /**
+ * The backend lacks a wire transfer method configuration option for the given instance. Thus, this instance is unavailable (not findable for creating new orders).
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_INSTANCE_CONFIGURATION_LACKS_WIRE"] = 2500] = "MERCHANT_PRIVATE_POST_ORDERS_INSTANCE_CONFIGURATION_LACKS_WIRE";
+ /**
+ * The proposal had no timestamp and the backend failed to obtain the local time. Likely to be an internal error.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_NO_LOCALTIME"] = 2501] = "MERCHANT_PRIVATE_POST_ORDERS_NO_LOCALTIME";
+ /**
+ * The order provided to the backend could not be parsed, some required fields were missing or ill-formed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR"] = 2502] = "MERCHANT_PRIVATE_POST_ORDERS_PROPOSAL_PARSE_ERROR";
+ /**
+ * The backend encountered an error: the proposal already exists.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS"] = 2503] = "MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS";
+ /**
+ * The request is invalid: the wire deadline is before the refund deadline.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE"] = 2504] = "MERCHANT_PRIVATE_POST_ORDERS_REFUND_AFTER_WIRE_DEADLINE";
+ /**
+ * The request is invalid: a delivery date was given, but it is in the past.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_DELIVERY_DATE_IN_PAST"] = 2505] = "MERCHANT_PRIVATE_POST_ORDERS_DELIVERY_DATE_IN_PAST";
+ /**
+ * The request is invalid: the wire deadline for the order would be "never".
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_WIRE_DEADLINE_IS_NEVER"] = 2506] = "MERCHANT_PRIVATE_POST_ORDERS_WIRE_DEADLINE_IS_NEVER";
+ /**
+ * One of the paths to forget is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_SYNTAX_INCORRECT"] = 2510] = "MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_SYNTAX_INCORRECT";
+ /**
+ * One of the paths to forget was not marked as forgettable.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_NOT_FORGETTABLE"] = 2511] = "MERCHANT_PRIVATE_PATCH_ORDERS_ID_FORGET_PATH_NOT_FORGETTABLE";
+ /**
+ * The order provided to the backend could not be deleted, our offer is still valid and awaiting payment.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_ORDERS_AWAITING_PAYMENT"] = 2520] = "MERCHANT_PRIVATE_DELETE_ORDERS_AWAITING_PAYMENT";
+ /**
+ * The order provided to the backend could not be deleted as the order was already paid.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_ORDERS_ALREADY_PAID"] = 2521] = "MERCHANT_PRIVATE_DELETE_ORDERS_ALREADY_PAID";
+ /**
+ * The amount to be refunded is inconsistent: either is lower than the previous amount being awarded, or it is too big to be paid back. In this second case, the fault stays on the business dept. side.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_INCONSISTENT_AMOUNT"] = 2530] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_INCONSISTENT_AMOUNT";
+ /**
+ * The frontend gave an unpaid order id to issue the refund to.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID"] = 2531] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_ORDER_UNPAID";
+ /**
+ * The refund delay was set to 0 and thus no refunds are allowed for this order.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_NOT_ALLOWED_BY_CONTRACT"] = 2532] = "MERCHANT_PRIVATE_POST_ORDERS_ID_REFUND_NOT_ALLOWED_BY_CONTRACT";
+ /**
+ * The exchange says it does not know this transfer.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_EXCHANGE_UNKNOWN"] = 2550] = "MERCHANT_PRIVATE_POST_TRANSFERS_EXCHANGE_UNKNOWN";
+ /**
+ * We internally failed to execute the /track/transfer request.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_REQUEST_ERROR"] = 2551] = "MERCHANT_PRIVATE_POST_TRANSFERS_REQUEST_ERROR";
+ /**
+ * The amount transferred differs between what was submitted and what the exchange claimed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_TRANSFERS"] = 2552] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_TRANSFERS";
+ /**
+ * The exchange gave conflicting information about a coin which has been wire transferred.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS"] = 2553] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS";
+ /**
+ * The exchange charged a different wire fee than what it originally advertised, and it is higher.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE"] = 2554] = "MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE";
+ /**
+ * We did not find the account that the transfer was made to.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND"] = 2555] = "MERCHANT_PRIVATE_POST_TRANSFERS_ACCOUNT_NOT_FOUND";
+ /**
+ * The backend could not delete the transfer as the echange already replied to our inquiry about it and we have integrated the result.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED"] = 2556] = "MERCHANT_PRIVATE_DELETE_TRANSFERS_ALREADY_CONFIRMED";
+ /**
+ * The backend was previously informed about a wire transfer with the same ID but a different amount. Multiple wire transfers with the same ID are not allowed. If the new amount is correct, the old transfer should first be deleted.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION"] = 2557] = "MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_SUBMISSION";
+ /**
+ * The merchant backend cannot create an instance under the given identifier as one already exists. Use PATCH to modify the existing entry.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS"] = 2600] = "MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS";
+ /**
+ * The merchant backend cannot create an instance because the authentication configuration field is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH"] = 2601] = "MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH";
+ /**
+ * The merchant backend cannot update an instance's authentication settings because the provided authentication settings are malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH"] = 2602] = "MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH";
+ /**
+ * The merchant backend cannot create an instance under the given identifier, the previous one was deleted but must be purged first.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_INSTANCES_PURGE_REQUIRED"] = 2603] = "MERCHANT_PRIVATE_POST_INSTANCES_PURGE_REQUIRED";
+ /**
+ * The merchant backend cannot update an instance under the given identifier, the previous one was deleted but must be purged first.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_INSTANCES_PURGE_REQUIRED"] = 2625] = "MERCHANT_PRIVATE_PATCH_INSTANCES_PURGE_REQUIRED";
+ /**
+ * The product ID exists.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS"] = 2650] = "MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS";
+ /**
+ * The update would have reduced the total amount of product lost, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_REDUCED"] = 2660] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_REDUCED";
+ /**
+ * The update would have mean that more stocks were lost than what remains from total inventory after sales, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS"] = 2661] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS";
+ /**
+ * The update would have reduced the total amount of product in stock, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED"] = 2662] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED";
+ /**
+ * The update would have reduced the total amount of product sold, which is not allowed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED"] = 2663] = "MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED";
+ /**
+ * The lock request is for more products than we have left (unlocked) in stock.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS"] = 2670] = "MERCHANT_PRIVATE_POST_PRODUCTS_LOCK_INSUFFICIENT_STOCKS";
+ /**
+ * The deletion request is for a product that is locked.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_PRODUCTS_CONFLICTING_LOCK"] = 2680] = "MERCHANT_PRIVATE_DELETE_PRODUCTS_CONFLICTING_LOCK";
+ /**
+ * The requested wire method is not supported by the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD"] = 2700] = "MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD";
+ /**
+ * The reserve could not be deleted because it is unknown.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_DELETE_RESERVES_NO_SUCH_RESERVE"] = 2710] = "MERCHANT_PRIVATE_DELETE_RESERVES_NO_SUCH_RESERVE";
+ /**
+ * The reserve that was used to fund the tips has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_EXPIRED"] = 2750] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_EXPIRED";
+ /**
+ * The reserve that was used to fund the tips was not found in the DB.
+ * Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_UNKNOWN"] = 2751] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_UNKNOWN";
+ /**
+ * The backend knows the instance that was supposed to support the tip, and it was configured for tipping. However, the funds remaining are insufficient to cover the tip, and the merchant should top up the reserve.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_INSUFFICIENT_FUNDS"] = 2752] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_INSUFFICIENT_FUNDS";
+ /**
+ * The backend failed to find a reserve needed to authorize the tip.
+ * Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE (503).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_NOT_FOUND"] = 2753] = "MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_RESERVE_NOT_FOUND";
+ /**
+ * The merchant backend encountered a failure in computing the deposit total.
+ * Returned with an HTTP status code of #MHD_HTTP_OK (200).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["MERCHANT_PRIVATE_GET_ORDERS_ID_AMOUNT_ARITHMETIC_FAILURE"] = 2800] = "MERCHANT_PRIVATE_GET_ORDERS_ID_AMOUNT_ARITHMETIC_FAILURE";
+ /**
+ * The signature from the exchange on the deposit confirmation is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["AUDITOR_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID"] = 3100] = "AUDITOR_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID";
+ /**
+ * The exchange key used for the signature on the deposit confirmation was revoked.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["AUDITOR_EXCHANGE_SIGNING_KEY_REVOKED"] = 3101] = "AUDITOR_EXCHANGE_SIGNING_KEY_REVOKED";
+ /**
+ * Wire transfer attempted with credit and debit party being the same bank account.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_SAME_ACCOUNT"] = 5101] = "BANK_SAME_ACCOUNT";
+ /**
+ * Wire transfer impossible, due to financial limitation of the party that attempted the payment.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_UNALLOWED_DEBIT"] = 5102] = "BANK_UNALLOWED_DEBIT";
+ /**
+ * Negative numbers are not allowed (as value and/or fraction) to instantiate an amount object.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_NEGATIVE_NUMBER_AMOUNT"] = 5103] = "BANK_NEGATIVE_NUMBER_AMOUNT";
+ /**
+ * A too big number was used (as value and/or fraction) to instantiate an amount object.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_NUMBER_TOO_BIG"] = 5104] = "BANK_NUMBER_TOO_BIG";
+ /**
+ * Could not login for the requested operation.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_LOGIN_FAILED"] = 5105] = "BANK_LOGIN_FAILED";
+ /**
+ * The bank account referenced in the requested operation was not found.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_UNKNOWN_ACCOUNT"] = 5106] = "BANK_UNKNOWN_ACCOUNT";
+ /**
+ * The transaction referenced in the requested operation (typically a reject operation), was not found.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_TRANSACTION_NOT_FOUND"] = 5107] = "BANK_TRANSACTION_NOT_FOUND";
+ /**
+ * Bank received a malformed amount string.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_BAD_FORMAT_AMOUNT"] = 5108] = "BANK_BAD_FORMAT_AMOUNT";
+ /**
+ * The client does not own the account credited by the transaction which is to be rejected, so it has no rights do reject it.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_REJECT_NO_RIGHTS"] = 5109] = "BANK_REJECT_NO_RIGHTS";
+ /**
+ * This error code is returned when no known exception types captured the exception.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_UNMANAGED_EXCEPTION"] = 5110] = "BANK_UNMANAGED_EXCEPTION";
+ /**
+ * This error code is used for all those exceptions that do not really need a specific error code to return to the client. Used for example when a client is trying to register with a unavailable username.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_SOFT_EXCEPTION"] = 5111] = "BANK_SOFT_EXCEPTION";
+ /**
+ * The request UID for a request to transfer funds has already been used, but with different details for the transfer.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_TRANSFER_REQUEST_UID_REUSED"] = 5112] = "BANK_TRANSFER_REQUEST_UID_REUSED";
+ /**
+ * The withdrawal operation already has a reserve selected. The current request conflicts with the existing selection.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT"] = 5113] = "BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT";
+ /**
+ * The wire transfer subject duplicates an existing reserve public key. But wire transfer subjects must be unique.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_DUPLICATE_RESERVE_PUB_SUBJECT"] = 5114] = "BANK_DUPLICATE_RESERVE_PUB_SUBJECT";
+ /**
+ * The client requested a transaction that is so far in the past, that it has been forgotten by the bank.
+ * Returned with an HTTP status code of #MHD_HTTP_GONE (410).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_ANCIENT_TRANSACTION_GONE"] = 5115] = "BANK_ANCIENT_TRANSACTION_GONE";
+ /**
+ * The client attempted to abort a transaction that was already confirmed.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_ABORT_CONFIRM_CONFLICT"] = 5116] = "BANK_ABORT_CONFIRM_CONFLICT";
+ /**
+ * The client attempted to confirm a transaction that was already aborted.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_CONFIRM_ABORT_CONFLICT"] = 5117] = "BANK_CONFIRM_ABORT_CONFLICT";
+ /**
+ * The client attempted to register an account with the same name.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_REGISTER_CONFLICT"] = 5118] = "BANK_REGISTER_CONFLICT";
+ /**
+ * The client attempted to confirm a withdrawal operation before the wallet posted the required details.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["BANK_POST_WITHDRAWAL_OPERATION_REQUIRED"] = 5119] = "BANK_POST_WITHDRAWAL_OPERATION_REQUIRED";
+ /**
+ * The sync service failed find the account in its database.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_ACCOUNT_UNKNOWN"] = 6100] = "SYNC_ACCOUNT_UNKNOWN";
+ /**
+ * The SHA-512 hash provided in the If-None-Match header is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_BAD_IF_NONE_MATCH"] = 6101] = "SYNC_BAD_IF_NONE_MATCH";
+ /**
+ * The SHA-512 hash provided in the If-Match header is malformed or missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_BAD_IF_MATCH"] = 6102] = "SYNC_BAD_IF_MATCH";
+ /**
+ * The signature provided in the "Sync-Signature" header is malformed or missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_BAD_SYNC_SIGNATURE"] = 6103] = "SYNC_BAD_SYNC_SIGNATURE";
+ /**
+ * The signature provided in the "Sync-Signature" header does not match the account, old or new Etags.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_INVALID_SIGNATURE"] = 6104] = "SYNC_INVALID_SIGNATURE";
+ /**
+ * The "Content-length" field for the upload is not a number.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_MALFORMED_CONTENT_LENGTH"] = 6105] = "SYNC_MALFORMED_CONTENT_LENGTH";
+ /**
+ * The "Content-length" field for the upload is too big based on the server's terms of service.
+ * Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_EXCESSIVE_CONTENT_LENGTH"] = 6106] = "SYNC_EXCESSIVE_CONTENT_LENGTH";
+ /**
+ * The server is out of memory to handle the upload. Trying again later may succeed.
+ * Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH"] = 6107] = "SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH";
+ /**
+ * The uploaded data does not match the Etag.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_INVALID_UPLOAD"] = 6108] = "SYNC_INVALID_UPLOAD";
+ /**
+ * HTTP server experienced a timeout while awaiting promised payment.
+ * Returned with an HTTP status code of #MHD_HTTP_REQUEST_TIMEOUT (408).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_PAYMENT_GENERIC_TIMEOUT"] = 6109] = "SYNC_PAYMENT_GENERIC_TIMEOUT";
+ /**
+ * Sync could not setup the payment request with its own backend.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_PAYMENT_CREATE_BACKEND_ERROR"] = 6110] = "SYNC_PAYMENT_CREATE_BACKEND_ERROR";
+ /**
+ * The sync service failed find the backup to be updated in its database.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_PREVIOUS_BACKUP_UNKNOWN"] = 6111] = "SYNC_PREVIOUS_BACKUP_UNKNOWN";
+ /**
+ * The "Content-length" field for the upload is missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_MISSING_CONTENT_LENGTH"] = 6112] = "SYNC_MISSING_CONTENT_LENGTH";
+ /**
+ * Sync had problems communicating with its payment backend.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_GENERIC_BACKEND_ERROR"] = 6113] = "SYNC_GENERIC_BACKEND_ERROR";
+ /**
+ * Sync experienced a timeout communicating with its payment backend.
+ * Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["SYNC_GENERIC_BACKEND_TIMEOUT"] = 6114] = "SYNC_GENERIC_BACKEND_TIMEOUT";
+ /**
+ * The wallet does not implement a version of the exchange protocol that is compatible with the protocol version of the exchange.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_IMPLEMENTED (501).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE"] = 7000] = "WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE";
+ /**
+ * The wallet encountered an unexpected exception. This is likely a bug in the wallet implementation.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_UNEXPECTED_EXCEPTION"] = 7001] = "WALLET_UNEXPECTED_EXCEPTION";
+ /**
+ * The wallet received a response from a server, but the response can't be parsed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_RECEIVED_MALFORMED_RESPONSE"] = 7002] = "WALLET_RECEIVED_MALFORMED_RESPONSE";
+ /**
+ * The wallet tried to make a network request, but it received no response.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_NETWORK_ERROR"] = 7003] = "WALLET_NETWORK_ERROR";
+ /**
+ * The wallet tried to make a network request, but it was throttled.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_HTTP_REQUEST_THROTTLED"] = 7004] = "WALLET_HTTP_REQUEST_THROTTLED";
+ /**
+ * The wallet made a request to a service, but received an error response it does not know how to handle.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_UNEXPECTED_REQUEST_ERROR"] = 7005] = "WALLET_UNEXPECTED_REQUEST_ERROR";
+ /**
+ * The denominations offered by the exchange are insufficient. Likely the exchange is badly configured or not maintained.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT"] = 7006] = "WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT";
+ /**
+ * The wallet does not support the operation requested by a client.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CORE_API_OPERATION_UNKNOWN"] = 7007] = "WALLET_CORE_API_OPERATION_UNKNOWN";
+ /**
+ * The given taler://pay URI is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_INVALID_TALER_PAY_URI"] = 7008] = "WALLET_INVALID_TALER_PAY_URI";
+ /**
+ * The signature on a coin by the exchange's denomination key is invalid after unblinding it.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_COIN_SIGNATURE_INVALID"] = 7009] = "WALLET_EXCHANGE_COIN_SIGNATURE_INVALID";
+ /**
+ * The exchange does not know about the reserve (yet), and thus withdrawal can't progress.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN_AT_EXCHANGE"] = 7010] = "WALLET_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN_AT_EXCHANGE";
+ /**
+ * The wallet core service is not available.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CORE_NOT_AVAILABLE"] = 7011] = "WALLET_CORE_NOT_AVAILABLE";
+ /**
+ * The bank has aborted a withdrawal operation, and thus a withdrawal can't complete.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK"] = 7012] = "WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK";
+ /**
+ * An HTTP request made by the wallet timed out.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_HTTP_REQUEST_GENERIC_TIMEOUT"] = 7013] = "WALLET_HTTP_REQUEST_GENERIC_TIMEOUT";
+ /**
+ * The order has already been claimed by another wallet.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_ORDER_ALREADY_CLAIMED"] = 7014] = "WALLET_ORDER_ALREADY_CLAIMED";
+ /**
+ * A group of withdrawal operations (typically for the same reserve at the same exchange) has errors and will be tried again later.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_WITHDRAWAL_GROUP_INCOMPLETE"] = 7015] = "WALLET_WITHDRAWAL_GROUP_INCOMPLETE";
+ /**
+ * The signature on a coin by the exchange's denomination key (obtained through the merchant via tipping) is invalid after unblinding it.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_TIPPING_COIN_SIGNATURE_INVALID"] = 7016] = "WALLET_TIPPING_COIN_SIGNATURE_INVALID";
+ /**
+ * The wallet does not implement a version of the bank integration API that is compatible with the version offered by the bank.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE"] = 7017] = "WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE";
+ /**
+ * The wallet processed a taler://pay URI, but the merchant base URL in the downloaded contract terms does not match the merchant base URL derived from the URI.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH"] = 7018] = "WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH";
+ /**
+ * The merchant's signature on the contract terms is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_SIGNATURE_INVALID"] = 7019] = "WALLET_CONTRACT_TERMS_SIGNATURE_INVALID";
+ /**
+ * The contract terms given by the merchant are malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CONTRACT_TERMS_MALFORMED"] = 7020] = "WALLET_CONTRACT_TERMS_MALFORMED";
+ /**
+ * A pending operation failed, and thus the request can't be completed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_PENDING_OPERATION_FAILED"] = 7021] = "WALLET_PENDING_OPERATION_FAILED";
+ /**
+ * A payment was attempted, but the merchant had an internal server error (5xx).
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_PAY_MERCHANT_SERVER_ERROR"] = 7022] = "WALLET_PAY_MERCHANT_SERVER_ERROR";
+ /**
+ * The crypto worker failed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CRYPTO_WORKER_ERROR"] = 7023] = "WALLET_CRYPTO_WORKER_ERROR";
+ /**
+ * The crypto worker received a bad request.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_CRYPTO_WORKER_BAD_REQUEST"] = 7024] = "WALLET_CRYPTO_WORKER_BAD_REQUEST";
+ /**
+ * A KYC step is required before withdrawal can proceed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["WALLET_WITHDRAWAL_KYC_REQUIRED"] = 7025] = "WALLET_WITHDRAWAL_KYC_REQUIRED";
+ /**
+ * We encountered a timeout with our payment backend.
+ * Returned with an HTTP status code of #MHD_HTTP_GATEWAY_TIMEOUT (504).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_BACKEND_TIMEOUT"] = 8000] = "ANASTASIS_GENERIC_BACKEND_TIMEOUT";
+ /**
+ * The backend requested payment, but the request is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST"] = 8001] = "ANASTASIS_GENERIC_INVALID_PAYMENT_REQUEST";
+ /**
+ * The backend got an unexpected reply from the payment processor.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_BACKEND_ERROR"] = 8002] = "ANASTASIS_GENERIC_BACKEND_ERROR";
+ /**
+ * The "Content-length" field for the upload is missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH"] = 8003] = "ANASTASIS_GENERIC_MISSING_CONTENT_LENGTH";
+ /**
+ * The "Content-length" field for the upload is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH"] = 8004] = "ANASTASIS_GENERIC_MALFORMED_CONTENT_LENGTH";
+ /**
+ * The backend failed to setup an order with the payment processor.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_ORDER_CREATE_BACKEND_ERROR"] = 8005] = "ANASTASIS_GENERIC_ORDER_CREATE_BACKEND_ERROR";
+ /**
+ * The backend was not authorized to check for payment with the payment processor.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PAYMENT_CHECK_UNAUTHORIZED"] = 8006] = "ANASTASIS_GENERIC_PAYMENT_CHECK_UNAUTHORIZED";
+ /**
+ * The backend could not check payment status with the payment processor.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PAYMENT_CHECK_START_FAILED"] = 8007] = "ANASTASIS_GENERIC_PAYMENT_CHECK_START_FAILED";
+ /**
+ * The Anastasis provider could not be reached.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_GENERIC_PROVIDER_UNREACHABLE"] = 8008] = "ANASTASIS_GENERIC_PROVIDER_UNREACHABLE";
+ /**
+ * HTTP server experienced a timeout while awaiting promised payment.
+ * Returned with an HTTP status code of #MHD_HTTP_REQUEST_TIMEOUT (408).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_PAYMENT_GENERIC_TIMEOUT"] = 8009] = "ANASTASIS_PAYMENT_GENERIC_TIMEOUT";
+ /**
+ * The key share is unknown to the provider.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UNKNOWN"] = 8108] = "ANASTASIS_TRUTH_UNKNOWN";
+ /**
+ * The authorization method used for the key share is no longer supported by the provider.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_AUTHORIZATION_METHOD_NO_LONGER_SUPPORTED"] = 8109] = "ANASTASIS_TRUTH_AUTHORIZATION_METHOD_NO_LONGER_SUPPORTED";
+ /**
+ * The client needs to respond to the challenge.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED"] = 8110] = "ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED";
+ /**
+ * The client's response to the challenge was invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_FAILED"] = 8111] = "ANASTASIS_TRUTH_CHALLENGE_FAILED";
+ /**
+ * The backend is not aware of having issued the provided challenge code. Either this is the wrong code, or it has expired.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_UNKNOWN"] = 8112] = "ANASTASIS_TRUTH_CHALLENGE_UNKNOWN";
+ /**
+ * The backend failed to initiate the authorization process.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED"] = 8114] = "ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED";
+ /**
+ * The authorization succeeded, but the key share is no longer available.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_KEY_SHARE_GONE"] = 8115] = "ANASTASIS_TRUTH_KEY_SHARE_GONE";
+ /**
+ * The backend forgot the order we asked the client to pay for
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_ORDER_DISAPPEARED"] = 8116] = "ANASTASIS_TRUTH_ORDER_DISAPPEARED";
+ /**
+ * The backend itself reported a bad exchange interaction.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_BACKEND_EXCHANGE_BAD"] = 8117] = "ANASTASIS_TRUTH_BACKEND_EXCHANGE_BAD";
+ /**
+ * The backend reported a payment status we did not expect.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UNEXPECTED_PAYMENT_STATUS"] = 8118] = "ANASTASIS_TRUTH_UNEXPECTED_PAYMENT_STATUS";
+ /**
+ * The backend failed to setup the order for payment.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_GATEWAY (502).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_PAYMENT_CREATE_BACKEND_ERROR"] = 8119] = "ANASTASIS_TRUTH_PAYMENT_CREATE_BACKEND_ERROR";
+ /**
+ * The decryption of the key share failed with the provided key.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_DECRYPTION_FAILED"] = 8120] = "ANASTASIS_TRUTH_DECRYPTION_FAILED";
+ /**
+ * The request rate is too high. The server is refusing requests to guard against brute-force attacks.
+ * Returned with an HTTP status code of #MHD_HTTP_TOO_MANY_REQUESTS (429).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_RATE_LIMITED"] = 8121] = "ANASTASIS_TRUTH_RATE_LIMITED";
+ /**
+ * A request to issue a challenge is not valid for this authentication method.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_CHALLENGE_WRONG_METHOD"] = 8123] = "ANASTASIS_TRUTH_CHALLENGE_WRONG_METHOD";
+ /**
+ * The backend failed to store the key share because the UUID is already in use.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UPLOAD_UUID_EXISTS"] = 8150] = "ANASTASIS_TRUTH_UPLOAD_UUID_EXISTS";
+ /**
+ * The backend failed to store the key share because the authorization method is not supported.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TRUTH_UPLOAD_METHOD_NOT_SUPPORTED"] = 8151] = "ANASTASIS_TRUTH_UPLOAD_METHOD_NOT_SUPPORTED";
+ /**
+ * The provided phone number is not an acceptable number.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_PHONE_INVALID"] = 8200] = "ANASTASIS_SMS_PHONE_INVALID";
+ /**
+ * Failed to run the SMS transmission helper process.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_HELPER_EXEC_FAILED"] = 8201] = "ANASTASIS_SMS_HELPER_EXEC_FAILED";
+ /**
+ * Provider failed to send SMS. Helper terminated with a non-successful result.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_SMS_HELPER_COMMAND_FAILED"] = 8202] = "ANASTASIS_SMS_HELPER_COMMAND_FAILED";
+ /**
+ * The provided email address is not an acceptable address.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_INVALID"] = 8210] = "ANASTASIS_EMAIL_INVALID";
+ /**
+ * Failed to run the E-mail transmission helper process.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_HELPER_EXEC_FAILED"] = 8211] = "ANASTASIS_EMAIL_HELPER_EXEC_FAILED";
+ /**
+ * Provider failed to send E-mail. Helper terminated with a non-successful result.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_EMAIL_HELPER_COMMAND_FAILED"] = 8212] = "ANASTASIS_EMAIL_HELPER_COMMAND_FAILED";
+ /**
+ * The provided postal address is not an acceptable address.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POST_INVALID"] = 8220] = "ANASTASIS_POST_INVALID";
+ /**
+ * Failed to run the mail transmission helper process.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POST_HELPER_EXEC_FAILED"] = 8221] = "ANASTASIS_POST_HELPER_EXEC_FAILED";
+ /**
+ * Provider failed to send mail. Helper terminated with a non-successful result.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POST_HELPER_COMMAND_FAILED"] = 8222] = "ANASTASIS_POST_HELPER_COMMAND_FAILED";
+ /**
+ * The provided IBAN address is not an acceptable IBAN.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_IBAN_INVALID"] = 8230] = "ANASTASIS_IBAN_INVALID";
+ /**
+ * The provider has not yet received the IBAN wire transfer authorizing the disclosure of the key share.
+ * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_IBAN_MISSING_TRANSFER"] = 8231] = "ANASTASIS_IBAN_MISSING_TRANSFER";
+ /**
+ * The backend did not find a TOTP key in the data provided.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TOTP_KEY_MISSING"] = 8240] = "ANASTASIS_TOTP_KEY_MISSING";
+ /**
+ * The key provided does not satisfy the format restrictions for an Anastasis TOTP key.
+ * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_TOTP_KEY_INVALID"] = 8241] = "ANASTASIS_TOTP_KEY_INVALID";
+ /**
+ * The given if-none-match header is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_IF_NONE_MATCH"] = 8301] = "ANASTASIS_POLICY_BAD_IF_NONE_MATCH";
+ /**
+ * The server is out of memory to handle the upload. Trying again later may succeed.
+ * Returned with an HTTP status code of #MHD_HTTP_PAYLOAD_TOO_LARGE (413).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_OUT_OF_MEMORY_ON_CONTENT_LENGTH"] = 8304] = "ANASTASIS_POLICY_OUT_OF_MEMORY_ON_CONTENT_LENGTH";
+ /**
+ * The signature provided in the "Anastasis-Policy-Signature" header is malformed or missing.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_SIGNATURE"] = 8305] = "ANASTASIS_POLICY_BAD_SIGNATURE";
+ /**
+ * The given if-match header is malformed.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_BAD_IF_MATCH"] = 8306] = "ANASTASIS_POLICY_BAD_IF_MATCH";
+ /**
+ * The uploaded data does not match the Etag.
+ * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_INVALID_UPLOAD"] = 8307] = "ANASTASIS_POLICY_INVALID_UPLOAD";
+ /**
+ * The provider is unaware of the requested policy.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_POLICY_NOT_FOUND"] = 8350] = "ANASTASIS_POLICY_NOT_FOUND";
+ /**
+ * The given action is invalid for the current state of the reducer.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_ACTION_INVALID"] = 8400] = "ANASTASIS_REDUCER_ACTION_INVALID";
+ /**
+ * The given state of the reducer is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_STATE_INVALID"] = 8401] = "ANASTASIS_REDUCER_STATE_INVALID";
+ /**
+ * The given input to the reducer is invalid.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_INVALID"] = 8402] = "ANASTASIS_REDUCER_INPUT_INVALID";
+ /**
+ * The selected authentication method does not work for the Anastasis provider.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED"] = 8403] = "ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED";
+ /**
+ * The given input and action do not work for the current state.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE"] = 8404] = "ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE";
+ /**
+ * We experienced an unexpected failure interacting with the backend.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_BACKEND_FAILURE"] = 8405] = "ANASTASIS_REDUCER_BACKEND_FAILURE";
+ /**
+ * The contents of a resource file did not match our expectations.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_RESOURCE_MALFORMED"] = 8406] = "ANASTASIS_REDUCER_RESOURCE_MALFORMED";
+ /**
+ * A required resource file is missing.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_RESOURCE_MISSING"] = 8407] = "ANASTASIS_REDUCER_RESOURCE_MISSING";
+ /**
+ * An input did not match the regular expression.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_REGEX_FAILED"] = 8408] = "ANASTASIS_REDUCER_INPUT_REGEX_FAILED";
+ /**
+ * An input did not match the custom validation logic.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED"] = 8409] = "ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED";
+ /**
+ * Our attempts to download the recovery document failed with all providers. Most likely the personal information you entered differs from the information you provided during the backup process and you should go back to the previous step. Alternatively, if you used a backup provider that is unknown to this application, you should add that provider manually.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED"] = 8410] = "ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED";
+ /**
+ * Anastasis provider reported a fatal failure.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_BACKUP_PROVIDER_FAILED"] = 8411] = "ANASTASIS_REDUCER_BACKUP_PROVIDER_FAILED";
+ /**
+ * Anastasis provider failed to respond to the configuration request.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED"] = 8412] = "ANASTASIS_REDUCER_PROVIDER_CONFIG_FAILED";
+ /**
+ * The policy we downloaded is malformed. Must have been a client error while creating the backup.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_POLICY_MALFORMED"] = 8413] = "ANASTASIS_REDUCER_POLICY_MALFORMED";
+ /**
+ * We failed to obtain the policy, likely due to a network issue.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_NETWORK_FAILED"] = 8414] = "ANASTASIS_REDUCER_NETWORK_FAILED";
+ /**
+ * The recovered secret did not match the required syntax.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_SECRET_MALFORMED"] = 8415] = "ANASTASIS_REDUCER_SECRET_MALFORMED";
+ /**
+ * The challenge data provided is too large for the available providers.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_CHALLENGE_DATA_TOO_BIG"] = 8416] = "ANASTASIS_REDUCER_CHALLENGE_DATA_TOO_BIG";
+ /**
+ * The provided core secret is too large for some of the providers.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_SECRET_TOO_BIG"] = 8417] = "ANASTASIS_REDUCER_SECRET_TOO_BIG";
+ /**
+ * The provider returned in invalid configuration.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG"] = 8418] = "ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG";
+ /**
+ * The reducer encountered an internal error, likely a bug that needs to be reported.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_INTERNAL_ERROR"] = 8419] = "ANASTASIS_REDUCER_INTERNAL_ERROR";
+ /**
+ * The reducer already synchronized with all providers.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED"] = 8420] = "ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED";
+ /**
+ * A generic error happened in the LibEuFin nexus. See the enclose details JSON for more information.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["LIBEUFIN_NEXUS_GENERIC_ERROR"] = 9000] = "LIBEUFIN_NEXUS_GENERIC_ERROR";
+ /**
+ * An uncaught exception happened in the LibEuFin nexus service.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION"] = 9001] = "LIBEUFIN_NEXUS_UNCAUGHT_EXCEPTION";
+ /**
+ * A generic error happened in the LibEuFin sandbox. See the enclose details JSON for more information.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["LIBEUFIN_SANDBOX_GENERIC_ERROR"] = 9500] = "LIBEUFIN_SANDBOX_GENERIC_ERROR";
+ /**
+ * An uncaught exception happened in the LibEuFin sandbox service.
+ * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["LIBEUFIN_SANDBOX_UNCAUGHT_EXCEPTION"] = 9501] = "LIBEUFIN_SANDBOX_UNCAUGHT_EXCEPTION";
+ /**
+ * This validation method is not supported by the service.
+ * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["TALDIR_METHOD_NOT_SUPPORTED"] = 9600] = "TALDIR_METHOD_NOT_SUPPORTED";
+ /**
+ * Number of allowed attempts for initiating a challenge exceeded.
+ * Returned with an HTTP status code of #MHD_HTTP_TOO_MANY_REQUESTS (429).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["TALDIR_REGISTER_RATE_LIMITED"] = 9601] = "TALDIR_REGISTER_RATE_LIMITED";
+ /**
+ * End of error code range.
+ * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+ * (A value of 0 indicates that the error is generated client-side).
+ */
+ TalerErrorCode[TalerErrorCode["END"] = 9999] = "END";
+})(TalerErrorCode || (TalerErrorCode = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2018-2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Type-safe codecs for converting from/to JSON.
+ */
+/* eslint-disable @typescript-eslint/ban-types */
+/**
+ * Error thrown when decoding fails.
+ */
+class DecodingError extends Error {
+ constructor(message) {
+ super(message);
+ Object.setPrototypeOf(this, DecodingError.prototype);
+ this.name = "DecodingError";
+ }
+}
+function renderContext(c) {
+ const p = c === null || c === void 0 ? void 0 : c.path;
+ if (p) {
+ return p.join(".");
+ }
+ else {
+ return "(unknown)";
+ }
+}
+function joinContext(c, part) {
+ var _a;
+ const path = (_a = c === null || c === void 0 ? void 0 : c.path) !== null && _a !== void 0 ? _a : [];
+ return {
+ path: path.concat([part]),
+ };
+}
+class ObjectCodecBuilder {
+ constructor() {
+ this.propList = [];
+ }
+ /**
+ * Define a property for the object.
+ */
+ property(x, codec) {
+ if (!codec) {
+ throw Error("inner codec must be defined");
+ }
+ this.propList.push({ name: x, codec: codec });
+ return this;
+ }
+ /**
+ * Return the built codec.
+ *
+ * @param objectDisplayName name of the object that this codec operates on,
+ * used in error messages.
+ */
+ build(objectDisplayName) {
+ const propList = this.propList;
+ return {
+ decode(x, c) {
+ if (!c) {
+ c = {
+ path: [`(${objectDisplayName})`],
+ };
+ }
+ if (typeof x !== "object") {
+ throw new DecodingError(`expected object for ${objectDisplayName} at ${renderContext(c)} but got ${typeof x}`);
+ }
+ const obj = {};
+ for (const prop of propList) {
+ const propRawVal = x[prop.name];
+ const propVal = prop.codec.decode(propRawVal, joinContext(c, prop.name));
+ obj[prop.name] = propVal;
+ }
+ return obj;
+ },
+ };
+ }
+}
+class UnionCodecBuilder {
+ constructor(discriminator, baseCodec) {
+ this.discriminator = discriminator;
+ this.baseCodec = baseCodec;
+ this.alternatives = new Map();
+ }
+ /**
+ * Define a property for the object.
+ */
+ alternative(tagValue, codec) {
+ if (!codec) {
+ throw Error("inner codec must be defined");
+ }
+ this.alternatives.set(tagValue, { codec, tagValue });
+ return this;
+ }
+ /**
+ * Return the built codec.
+ *
+ * @param objectDisplayName name of the object that this codec operates on,
+ * used in error messages.
+ */
+ build(objectDisplayName) {
+ const alternatives = this.alternatives;
+ const discriminator = this.discriminator;
+ const baseCodec = this.baseCodec;
+ return {
+ decode(x, c) {
+ if (!c) {
+ c = {
+ path: [`(${objectDisplayName})`],
+ };
+ }
+ const d = x[discriminator];
+ if (d === undefined) {
+ throw new DecodingError(`expected tag for ${objectDisplayName} at ${renderContext(c)}.${String(discriminator)}`);
+ }
+ const alt = alternatives.get(d);
+ if (!alt) {
+ throw new DecodingError(`unknown tag for ${objectDisplayName} ${d} at ${renderContext(c)}.${String(discriminator)}`);
+ }
+ const altDecoded = alt.codec.decode(x);
+ if (baseCodec) {
+ const baseDecoded = baseCodec.decode(x, c);
+ return Object.assign(Object.assign({}, baseDecoded), altDecoded);
+ }
+ else {
+ return altDecoded;
+ }
+ },
+ };
+ }
+}
+class UnionCodecPreBuilder {
+ discriminateOn(discriminator, baseCodec) {
+ return new UnionCodecBuilder(discriminator, baseCodec);
+ }
+}
+/**
+ * Return a builder for a codec that decodes an object with properties.
+ */
+function buildCodecForObject() {
+ return new ObjectCodecBuilder();
+}
+function buildCodecForUnion() {
+ return new UnionCodecPreBuilder();
+}
+/**
+ * Return a codec for a mapping from a string to values described by the inner codec.
+ */
+function codecForMap(innerCodec) {
+ if (!innerCodec) {
+ throw Error("inner codec must be defined");
+ }
+ return {
+ decode(x, c) {
+ const map = {};
+ if (typeof x !== "object") {
+ throw new DecodingError(`expected object at ${renderContext(c)}`);
+ }
+ for (const i in x) {
+ map[i] = innerCodec.decode(x[i], joinContext(c, `[${i}]`));
+ }
+ return map;
+ },
+ };
+}
+/**
+ * Return a codec for a list, containing values described by the inner codec.
+ */
+function codecForList(innerCodec) {
+ if (!innerCodec) {
+ throw Error("inner codec must be defined");
+ }
+ return {
+ decode(x, c) {
+ const arr = [];
+ if (!Array.isArray(x)) {
+ throw new DecodingError(`expected array at ${renderContext(c)}`);
+ }
+ for (const i in x) {
+ arr.push(innerCodec.decode(x[i], joinContext(c, `[${i}]`)));
+ }
+ return arr;
+ },
+ };
+}
+/**
+ * Return a codec for a value that must be a number.
+ */
+function codecForNumber() {
+ return {
+ decode(x, c) {
+ if (typeof x === "number") {
+ return x;
+ }
+ throw new DecodingError(`expected number at ${renderContext(c)} but got ${typeof x}`);
+ },
+ };
+}
+/**
+ * Return a codec for a value that must be a number.
+ */
+function codecForBoolean() {
+ return {
+ decode(x, c) {
+ if (typeof x === "boolean") {
+ return x;
+ }
+ throw new DecodingError(`expected boolean at ${renderContext(c)} but got ${typeof x}`);
+ },
+ };
+}
+/**
+ * Return a codec for a value that must be a string.
+ */
+function codecForString() {
+ return {
+ decode(x, c) {
+ if (typeof x === "string") {
+ return x;
+ }
+ throw new DecodingError(`expected string at ${renderContext(c)} but got ${typeof x}`);
+ },
+ };
+}
+/**
+ * Codec that allows any value.
+ */
+function codecForAny() {
+ return {
+ decode(x, c) {
+ return x;
+ },
+ };
+}
+/**
+ * Return a codec for a value that must be a string.
+ */
+function codecForConstString(s) {
+ return {
+ decode(x, c) {
+ if (x === s) {
+ return x;
+ }
+ if (typeof x !== "string") {
+ throw new DecodingError(`expected string constant "${s}" at ${renderContext(c)} but got ${typeof x}`);
+ }
+ throw new DecodingError(`expected string constant "${s}" at ${renderContext(c)} but got string value "${x}"`);
+ },
+ };
+}
+/**
+ * Return a codec for a value that must be a constant number.
+ */
+function codecForConstNumber(n) {
+ return {
+ decode(x, c) {
+ if (x === n) {
+ return x;
+ }
+ throw new DecodingError(`expected number constant "${n}" at ${renderContext(c)} but got ${typeof x}`);
+ },
+ };
+}
+function codecOptional(innerCodec) {
+ return {
+ decode(x, c) {
+ if (x === undefined || x === null) {
+ return undefined;
+ }
+ return innerCodec.decode(x, c);
+ },
+ };
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Number of fractional units that one value unit represents.
+ */
+const amountFractionalBase = 1e8;
+/**
+ * How many digits behind the comma are required to represent the
+ * fractional value in human readable decimal format? Must match
+ * lg(fractionalBase)
+ */
+const amountFractionalLength = 8;
+/**
+ * Maximum allowed value field of an amount.
+ */
+const amountMaxValue = Math.pow(2, 52);
+const codecForAmountString = () => codecForString();
+/**
+ * Helper class for dealing with amounts.
+ */
+class Amounts {
+ constructor() {
+ throw Error("not instantiable");
+ }
+ static currencyOf(amount) {
+ const amt = Amounts.parseOrThrow(amount);
+ return amt.currency;
+ }
+ static zeroOfAmount(amount) {
+ const amt = Amounts.parseOrThrow(amount);
+ return {
+ currency: amt.currency,
+ fraction: 0,
+ value: 0,
+ };
+ }
+ /**
+ * Get an amount that represents zero units of a currency.
+ */
+ static zeroOfCurrency(currency) {
+ return {
+ currency,
+ fraction: 0,
+ value: 0,
+ };
+ }
+ static jsonifyAmount(amt) {
+ if (typeof amt === "string") {
+ return Amounts.parseOrThrow(amt);
+ }
+ return amt;
+ }
+ static sum(amounts) {
+ if (amounts.length <= 0) {
+ throw Error("can't sum zero amounts");
+ }
+ const jsonAmounts = amounts.map((x) => Amounts.jsonifyAmount(x));
+ return Amounts.add(jsonAmounts[0], ...jsonAmounts.slice(1));
+ }
+ static sumOrZero(currency, amounts) {
+ if (amounts.length <= 0) {
+ return {
+ amount: Amounts.zeroOfCurrency(currency),
+ saturated: false,
+ };
+ }
+ const jsonAmounts = amounts.map((x) => Amounts.jsonifyAmount(x));
+ return Amounts.add(jsonAmounts[0], ...jsonAmounts.slice(1));
+ }
+ /**
+ * Add two amounts. Return the result and whether
+ * the addition overflowed. The overflow is always handled
+ * by saturating and never by wrapping.
+ *
+ * Throws when currencies don't match.
+ */
+ static add(first, ...rest) {
+ const firstJ = Amounts.jsonifyAmount(first);
+ const currency = firstJ.currency;
+ let value = firstJ.value + Math.floor(firstJ.fraction / amountFractionalBase);
+ if (value > amountMaxValue) {
+ return {
+ amount: {
+ currency,
+ value: amountMaxValue,
+ fraction: amountFractionalBase - 1,
+ },
+ saturated: true,
+ };
+ }
+ let fraction = firstJ.fraction % amountFractionalBase;
+ for (const x of rest) {
+ const xJ = Amounts.jsonifyAmount(x);
+ if (xJ.currency.toUpperCase() !== currency.toUpperCase()) {
+ throw Error(`Mismatched currency: ${xJ.currency} and ${currency}`);
+ }
+ value =
+ value +
+ xJ.value +
+ Math.floor((fraction + xJ.fraction) / amountFractionalBase);
+ fraction = Math.floor((fraction + xJ.fraction) % amountFractionalBase);
+ if (value > amountMaxValue) {
+ return {
+ amount: {
+ currency,
+ value: amountMaxValue,
+ fraction: amountFractionalBase - 1,
+ },
+ saturated: true,
+ };
+ }
+ }
+ return { amount: { currency, value, fraction }, saturated: false };
+ }
+ /**
+ * Subtract two amounts. Return the result and whether
+ * the subtraction overflowed. The overflow is always handled
+ * by saturating and never by wrapping.
+ *
+ * Throws when currencies don't match.
+ */
+ static sub(a, ...rest) {
+ const aJ = Amounts.jsonifyAmount(a);
+ const currency = aJ.currency;
+ let value = aJ.value;
+ let fraction = aJ.fraction;
+ for (const b of rest) {
+ const bJ = Amounts.jsonifyAmount(b);
+ if (bJ.currency.toUpperCase() !== aJ.currency.toUpperCase()) {
+ throw Error(`Mismatched currency: ${bJ.currency} and ${currency}`);
+ }
+ if (fraction < bJ.fraction) {
+ if (value < 1) {
+ return {
+ amount: { currency, value: 0, fraction: 0 },
+ saturated: true,
+ };
+ }
+ value--;
+ fraction += amountFractionalBase;
+ }
+ console.assert(fraction >= bJ.fraction);
+ fraction -= bJ.fraction;
+ if (value < bJ.value) {
+ return { amount: { currency, value: 0, fraction: 0 }, saturated: true };
+ }
+ value -= bJ.value;
+ }
+ return { amount: { currency, value, fraction }, saturated: false };
+ }
+ /**
+ * Compare two amounts. Returns 0 when equal, -1 when a < b
+ * and +1 when a > b. Throws when currencies don't match.
+ */
+ static cmp(a, b) {
+ a = Amounts.jsonifyAmount(a);
+ b = Amounts.jsonifyAmount(b);
+ if (a.currency !== b.currency) {
+ throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
+ }
+ const av = a.value + Math.floor(a.fraction / amountFractionalBase);
+ const af = a.fraction % amountFractionalBase;
+ const bv = b.value + Math.floor(b.fraction / amountFractionalBase);
+ const bf = b.fraction % amountFractionalBase;
+ switch (true) {
+ case av < bv:
+ return -1;
+ case av > bv:
+ return 1;
+ case af < bf:
+ return -1;
+ case af > bf:
+ return 1;
+ case af === bf:
+ return 0;
+ default:
+ throw Error("assertion failed");
+ }
+ }
+ /**
+ * Create a copy of an amount.
+ */
+ static copy(a) {
+ return {
+ currency: a.currency,
+ fraction: a.fraction,
+ value: a.value,
+ };
+ }
+ /**
+ * Divide an amount. Throws on division by zero.
+ */
+ static divide(a, n) {
+ if (n === 0) {
+ throw Error(`Division by 0`);
+ }
+ if (n === 1) {
+ return { value: a.value, fraction: a.fraction, currency: a.currency };
+ }
+ const r = a.value % n;
+ return {
+ currency: a.currency,
+ fraction: Math.floor((r * amountFractionalBase + a.fraction) / n),
+ value: Math.floor(a.value / n),
+ };
+ }
+ /**
+ * Check if an amount is non-zero.
+ */
+ static isNonZero(a) {
+ return a.value > 0 || a.fraction > 0;
+ }
+ static isZero(a) {
+ a = Amounts.jsonifyAmount(a);
+ return a.value === 0 && a.fraction === 0;
+ }
+ /**
+ * Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
+ */
+ static parse(s) {
+ const res = s.match(/^([a-zA-Z0-9_*-]+):([0-9]+)([.][0-9]+)?$/);
+ if (!res) {
+ return undefined;
+ }
+ const tail = res[3] || ".0";
+ if (tail.length > amountFractionalLength + 1) {
+ return undefined;
+ }
+ const value = Number.parseInt(res[2]);
+ if (value > amountMaxValue) {
+ return undefined;
+ }
+ return {
+ currency: res[1].toUpperCase(),
+ fraction: Math.round(amountFractionalBase * Number.parseFloat(tail)),
+ value,
+ };
+ }
+ /**
+ * Parse amount in standard string form (like 'EUR:20.5'),
+ * throw if the input is not a valid amount.
+ */
+ static parseOrThrow(s) {
+ if (typeof s === "object") {
+ if (typeof s.currency !== "string") {
+ throw Error("invalid amount object");
+ }
+ if (typeof s.value !== "number") {
+ throw Error("invalid amount object");
+ }
+ if (typeof s.fraction !== "number") {
+ throw Error("invalid amount object");
+ }
+ return { currency: s.currency, value: s.value, fraction: s.fraction };
+ }
+ else if (typeof s === "string") {
+ const res = Amounts.parse(s);
+ if (!res) {
+ throw Error(`Can't parse amount: "${s}"`);
+ }
+ return res;
+ }
+ else {
+ throw Error("invalid amount (illegal type)");
+ }
+ }
+ /**
+ * Convert a float to a Taler amount.
+ * Loss of precision possible.
+ */
+ static fromFloat(floatVal, currency) {
+ return {
+ currency,
+ fraction: Math.floor((floatVal - Math.floor(floatVal)) * amountFractionalBase),
+ value: Math.floor(floatVal),
+ };
+ }
+ static min(a, b) {
+ const cr = Amounts.cmp(a, b);
+ if (cr >= 0) {
+ return Amounts.jsonifyAmount(b);
+ }
+ else {
+ return Amounts.jsonifyAmount(a);
+ }
+ }
+ static max(a, b) {
+ const cr = Amounts.cmp(a, b);
+ if (cr >= 0) {
+ return Amounts.jsonifyAmount(a);
+ }
+ else {
+ return Amounts.jsonifyAmount(b);
+ }
+ }
+ static mult(a, n) {
+ a = this.jsonifyAmount(a);
+ if (!Number.isInteger(n)) {
+ throw Error("amount can only be multipied by an integer");
+ }
+ if (n < 0) {
+ throw Error("amount can only be multiplied by a positive integer");
+ }
+ if (n == 0) {
+ return {
+ amount: Amounts.zeroOfCurrency(a.currency),
+ saturated: false,
+ };
+ }
+ let x = a;
+ let acc = Amounts.zeroOfCurrency(a.currency);
+ while (n > 1) {
+ if (n % 2 == 0) {
+ n = n / 2;
+ }
+ else {
+ n = (n - 1) / 2;
+ const r2 = Amounts.add(acc, x);
+ if (r2.saturated) {
+ return r2;
+ }
+ acc = r2.amount;
+ }
+ const r2 = Amounts.add(x, x);
+ if (r2.saturated) {
+ return r2;
+ }
+ x = r2.amount;
+ }
+ return Amounts.add(acc, x);
+ }
+ /**
+ * Check if the argument is a valid amount in string form.
+ */
+ static check(a) {
+ if (typeof a !== "string") {
+ return false;
+ }
+ try {
+ const parsedAmount = Amounts.parse(a);
+ return !!parsedAmount;
+ }
+ catch (_a) {
+ return false;
+ }
+ }
+ /**
+ * Convert to standard human-readable string representation that's
+ * also used in JSON formats.
+ */
+ static stringify(a) {
+ a = Amounts.jsonifyAmount(a);
+ const s = this.stringifyValue(a);
+ return `${a.currency}:${s}`;
+ }
+ static isSameCurrency(a1, a2) {
+ const x1 = this.jsonifyAmount(a1);
+ const x2 = this.jsonifyAmount(a2);
+ return x1.currency.toUpperCase() === x2.currency.toUpperCase();
+ }
+ static stringifyValue(a, minFractional = 0) {
+ const aJ = Amounts.jsonifyAmount(a);
+ const av = aJ.value + Math.floor(aJ.fraction / amountFractionalBase);
+ const af = aJ.fraction % amountFractionalBase;
+ let s = av.toString();
+ if (af) {
+ s = s + ".";
+ let n = af;
+ for (let i = 0; i < amountFractionalLength; i++) {
+ if (!n && i >= minFractional) {
+ break;
+ }
+ s = s + Math.floor((n / amountFractionalBase) * 10).toString();
+ n = (n * 10) % amountFractionalBase;
+ }
+ }
+ return s;
+ }
+ /**
+ * Number of fractional digits needed to fully represent the amount
+ * @param a amount
+ * @returns
+ */
+ static maxFractionalDigits(a) {
+ if (a.fraction === 0)
+ return 0;
+ if (a.fraction < 0) {
+ console.error("amount fraction can not be negative", a);
+ return 0;
+ }
+ let i = 0;
+ let check = true;
+ let rest = a.fraction;
+ while (rest > 0 && check) {
+ check = rest % 10 === 0;
+ rest = rest / 10;
+ i++;
+ }
+ return amountFractionalLength - i + 1;
+ }
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Major version. Each increment means a backwards-incompatible change.
+ * Typically this means that a custom converter needs to be written.
+ */
+const BACKUP_VERSION_MAJOR = 1;
+/**
+ * Minor version. Each increment means that information is added to the backup
+ * in a backwards-compatible way.
+ *
+ * Wallets can always import a smaller minor version than their own backup code version.
+ * When importing a bigger version, data loss is possible and the user should be urged to
+ * upgrade their wallet first.
+ */
+const BACKUP_VERSION_MINOR = 1;
+var BackupOperationStatus;
+(function (BackupOperationStatus) {
+ BackupOperationStatus["Cancelled"] = "cancelled";
+ BackupOperationStatus["Finished"] = "finished";
+ BackupOperationStatus["Pending"] = "pending";
+})(BackupOperationStatus || (BackupOperationStatus = {}));
+var BackupWgType;
+(function (BackupWgType) {
+ BackupWgType["BankManual"] = "bank-manual";
+ BackupWgType["BankIntegrated"] = "bank-integrated";
+ BackupWgType["PeerPullCredit"] = "peer-pull-credit";
+ BackupWgType["PeerPushCredit"] = "peer-push-credit";
+ BackupWgType["Recoup"] = "recoup";
+})(BackupWgType || (BackupWgType = {}));
+/**
+ * Types of coin sources.
+ */
+var BackupCoinSourceType;
+(function (BackupCoinSourceType) {
+ BackupCoinSourceType["Withdraw"] = "withdraw";
+ BackupCoinSourceType["Refresh"] = "refresh";
+ BackupCoinSourceType["Tip"] = "tip";
+})(BackupCoinSourceType || (BackupCoinSourceType = {}));
+/**
+ * Reasons for why a coin is being refreshed.
+ */
+var BackupRefreshReason;
+(function (BackupRefreshReason) {
+ BackupRefreshReason["Manual"] = "manual";
+ BackupRefreshReason["Pay"] = "pay";
+ BackupRefreshReason["Refund"] = "refund";
+ BackupRefreshReason["AbortPay"] = "abort-pay";
+ BackupRefreshReason["Recoup"] = "recoup";
+ BackupRefreshReason["BackupRestored"] = "backup-restored";
+ BackupRefreshReason["Scheduled"] = "scheduled";
+})(BackupRefreshReason || (BackupRefreshReason = {}));
+var BackupRefundState;
+(function (BackupRefundState) {
+ BackupRefundState["Failed"] = "failed";
+ BackupRefundState["Applied"] = "applied";
+ BackupRefundState["Pending"] = "pending";
+})(BackupRefundState || (BackupRefundState = {}));
+var BackupProposalStatus;
+(function (BackupProposalStatus) {
+ /**
+ * Proposed (and either downloaded or not,
+ * depending on whether contract terms are present),
+ * but the user needs to accept/reject it.
+ */
+ BackupProposalStatus["Proposed"] = "proposed";
+ /**
+ * The user has rejected the proposal.
+ */
+ BackupProposalStatus["Refused"] = "refused";
+ /**
+ * Downloading or processing the proposal has failed permanently.
+ *
+ * FIXME: Should this be modeled as a "misbehavior report" instead?
+ */
+ BackupProposalStatus["PermanentlyFailed"] = "permanently-failed";
+ /**
+ * Downloaded proposal was detected as a re-purchase.
+ */
+ BackupProposalStatus["Repurchase"] = "repurchase";
+ BackupProposalStatus["Paid"] = "paid";
+})(BackupProposalStatus || (BackupProposalStatus = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+// globalThis polyfill, see https://mathiasbynens.be/notes/globalthis
+(function () {
+ if (typeof globalThis === "object")
+ return;
+ Object.defineProperty(Object.prototype, "__magic__", {
+ get: function () {
+ return this;
+ },
+ configurable: true, // This makes it possible to `delete` the getter later.
+ });
+ // @ts-ignore: polyfill magic
+ __magic__.globalThis = __magic__; // lolwat
+ // @ts-ignore: polyfill magic
+ delete Object.prototype.__magic__;
+})();
+// @ts-ignore
+const _URL = globalThis.URL;
+if (!_URL) {
+ throw Error("FATAL: URL not available");
+}
+const URL$1 = _URL;
+// @ts-ignore
+const _URLSearchParams = globalThis.URLSearchParams;
+if (!_URLSearchParams) {
+ throw Error("FATAL: URLSearchParams not available");
+}
+const URLSearchParams = _URLSearchParams;
+
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ 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/>
+ */
+/**
+ * Show an amount in a form suitable for the user.
+ * FIXME: In the future, this should consider currency-specific
+ * settings such as significant digits or currency symbols.
+ */
+function amountToPretty(amount) {
+ const x = amount.value + amount.fraction / amountFractionalBase;
+ return `${x} ${amount.currency}`;
+}
+/**
+ * Canonicalize a base url, typically for the exchange.
+ *
+ * See http://api.taler.net/wallet.html#general
+ */
+function canonicalizeBaseUrl(url) {
+ if (!url.startsWith("http") && !url.startsWith("https")) {
+ url = "https://" + url;
+ }
+ const x = new URL$1(url);
+ if (!x.pathname.endsWith("/")) {
+ x.pathname = x.pathname + "/";
+ }
+ x.search = "";
+ x.hash = "";
+ return x.href;
+}
+/**
+ * Convert object to JSON with canonical ordering of keys
+ * and whitespace omitted.
+ *
+ * See RFC 4885 (https://tools.ietf.org/html/rfc8785).
+ */
+function canonicalJson(obj) {
+ // Check for cycles, etc.
+ obj = JSON.parse(JSON.stringify(obj));
+ if (typeof obj === "string") {
+ return JSON.stringify(obj);
+ }
+ if (typeof obj === "number" || typeof obj === "boolean" || obj === null) {
+ return JSON.stringify(obj);
+ }
+ if (Array.isArray(obj)) {
+ const objs = obj.map((e) => canonicalJson(e));
+ return `[${objs.join(",")}]`;
+ }
+ const keys = [];
+ for (const key in obj) {
+ keys.push(key);
+ }
+ keys.sort();
+ let s = "{";
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i];
+ s += JSON.stringify(key) + ":" + canonicalJson(obj[key]);
+ if (i !== keys.length - 1) {
+ s += ",";
+ }
+ }
+ return s + "}";
+}
+/**
+ * Lexically compare two strings.
+ */
+function strcmp(s1, s2) {
+ if (s1 < s2) {
+ return -1;
+ }
+ if (s1 > s2) {
+ return 1;
+ }
+ return 0;
+}
+/**
+ * Shorthand function for formatted JSON stringification.
+ */
+function j2s(x) {
+ return JSON.stringify(x, undefined, 2);
+}
+/**
+ * Use this to filter null or undefined from an array in a type-safe fashion
+ *
+ * example:
+ * const array: Array<T | undefined> = [undefined, null]
+ * const filtered: Array<T> = array.filter(notEmpty)
+ *
+ * @param value
+ * @returns
+ */
+function notEmpty(value) {
+ return value !== null && value !== undefined;
+}
+
+/*
+ This file is part of TALER
+ (C) 2017 GNUnet e.V.
+
+ 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 LibtoolVersion;
+(function (LibtoolVersion) {
+ /**
+ * Compare two libtool-style version strings.
+ */
+ function compare(me, other) {
+ const meVer = parseVersion(me);
+ const otherVer = parseVersion(other);
+ if (!(meVer && otherVer)) {
+ return undefined;
+ }
+ const compatible = meVer.current - meVer.age <= otherVer.current &&
+ meVer.current >= otherVer.current - otherVer.age;
+ const currentCmp = Math.sign(meVer.current - otherVer.current);
+ return { compatible, currentCmp };
+ }
+ LibtoolVersion.compare = compare;
+ function parseVersion(v) {
+ const [currentStr, revisionStr, ageStr, ...rest] = v.split(":");
+ if (rest.length !== 0) {
+ return undefined;
+ }
+ const current = Number.parseInt(currentStr);
+ const revision = Number.parseInt(revisionStr);
+ const age = Number.parseInt(ageStr);
+ if (Number.isNaN(current)) {
+ return undefined;
+ }
+ if (Number.isNaN(revision)) {
+ return undefined;
+ }
+ if (Number.isNaN(age)) {
+ return undefined;
+ }
+ return { current, revision, age };
+ }
+ LibtoolVersion.parseVersion = parseVersion;
+})(LibtoolVersion || (LibtoolVersion = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var NotificationType;
+(function (NotificationType) {
+ NotificationType["CoinWithdrawn"] = "coin-withdrawn";
+ NotificationType["ProposalAccepted"] = "proposal-accepted";
+ NotificationType["ProposalDownloaded"] = "proposal-downloaded";
+ NotificationType["RefundsSubmitted"] = "refunds-submitted";
+ NotificationType["RecoupStarted"] = "recoup-started";
+ NotificationType["RecoupFinished"] = "recoup-finished";
+ NotificationType["RefreshRevealed"] = "refresh-revealed";
+ NotificationType["RefreshMelted"] = "refresh-melted";
+ NotificationType["RefreshStarted"] = "refresh-started";
+ NotificationType["RefreshUnwarranted"] = "refresh-unwarranted";
+ NotificationType["ReserveUpdated"] = "reserve-updated";
+ NotificationType["ReserveConfirmed"] = "reserve-confirmed";
+ NotificationType["ReserveCreated"] = "reserve-created";
+ NotificationType["WithdrawGroupCreated"] = "withdraw-group-created";
+ NotificationType["WithdrawGroupFinished"] = "withdraw-group-finished";
+ NotificationType["WaitingForRetry"] = "waiting-for-retry";
+ NotificationType["RefundStarted"] = "refund-started";
+ NotificationType["RefundQueried"] = "refund-queried";
+ NotificationType["RefundFinished"] = "refund-finished";
+ NotificationType["ExchangeOperationError"] = "exchange-operation-error";
+ NotificationType["ExchangeAdded"] = "exchange-added";
+ NotificationType["RefreshOperationError"] = "refresh-operation-error";
+ NotificationType["RecoupOperationError"] = "recoup-operation-error";
+ NotificationType["RefundApplyOperationError"] = "refund-apply-error";
+ NotificationType["RefundStatusOperationError"] = "refund-status-error";
+ NotificationType["ProposalOperationError"] = "proposal-error";
+ NotificationType["BackupOperationError"] = "backup-error";
+ NotificationType["TipOperationError"] = "tip-error";
+ NotificationType["PayOperationError"] = "pay-error";
+ NotificationType["PayOperationSuccess"] = "pay-operation-success";
+ NotificationType["WithdrawOperationError"] = "withdraw-error";
+ NotificationType["ReserveNotYetFound"] = "reserve-not-yet-found";
+ NotificationType["ReserveOperationError"] = "reserve-error";
+ NotificationType["InternalError"] = "internal-error";
+ NotificationType["PendingOperationProcessed"] = "pending-operation-processed";
+ NotificationType["ProposalRefused"] = "proposal-refused";
+ NotificationType["ReserveRegisteredWithBank"] = "reserve-registered-with-bank";
+ NotificationType["DepositOperationError"] = "deposit-operation-error";
+})(NotificationType || (NotificationType = {}));
+
+// SHA-256 for JavaScript.
+//
+// Written in 2014-2016 by Dmitry Chestnykh.
+// Public domain, no warranty.
+//
+// Functions (accept and return Uint8Arrays):
+//
+// sha256(message) -> hash
+// sha256.hmac(key, message) -> mac
+//
+// Classes:
+//
+// new sha256.Hash()
+const digestLength = 32;
+const blockSize = 64;
+// SHA-256 constants
+const K = new Uint32Array([
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+]);
+function hashBlocks(w, v, p, pos, len) {
+ let a, b, c, d, e, f, g, h, u, i, j, t1, t2;
+ while (len >= 64) {
+ a = v[0];
+ b = v[1];
+ c = v[2];
+ d = v[3];
+ e = v[4];
+ f = v[5];
+ g = v[6];
+ h = v[7];
+ for (i = 0; i < 16; i++) {
+ j = pos + i * 4;
+ w[i] =
+ ((p[j] & 0xff) << 24) |
+ ((p[j + 1] & 0xff) << 16) |
+ ((p[j + 2] & 0xff) << 8) |
+ (p[j + 3] & 0xff);
+ }
+ for (i = 16; i < 64; i++) {
+ u = w[i - 2];
+ t1 =
+ ((u >>> 17) | (u << (32 - 17))) ^
+ ((u >>> 19) | (u << (32 - 19))) ^
+ (u >>> 10);
+ u = w[i - 15];
+ t2 =
+ ((u >>> 7) | (u << (32 - 7))) ^
+ ((u >>> 18) | (u << (32 - 18))) ^
+ (u >>> 3);
+ w[i] = ((t1 + w[i - 7]) | 0) + ((t2 + w[i - 16]) | 0);
+ }
+ for (i = 0; i < 64; i++) {
+ t1 =
+ ((((((e >>> 6) | (e << (32 - 6))) ^
+ ((e >>> 11) | (e << (32 - 11))) ^
+ ((e >>> 25) | (e << (32 - 25)))) +
+ ((e & f) ^ (~e & g))) |
+ 0) +
+ ((h + ((K[i] + w[i]) | 0)) | 0)) |
+ 0;
+ t2 =
+ ((((a >>> 2) | (a << (32 - 2))) ^
+ ((a >>> 13) | (a << (32 - 13))) ^
+ ((a >>> 22) | (a << (32 - 22)))) +
+ ((a & b) ^ (a & c) ^ (b & c))) |
+ 0;
+ h = g;
+ g = f;
+ f = e;
+ e = (d + t1) | 0;
+ d = c;
+ c = b;
+ b = a;
+ a = (t1 + t2) | 0;
+ }
+ v[0] += a;
+ v[1] += b;
+ v[2] += c;
+ v[3] += d;
+ v[4] += e;
+ v[5] += f;
+ v[6] += g;
+ v[7] += h;
+ pos += 64;
+ len -= 64;
+ }
+ return pos;
+}
+// Hash implements SHA256 hash algorithm.
+class HashSha256 {
+ constructor() {
+ this.digestLength = digestLength;
+ this.blockSize = blockSize;
+ // Note: Int32Array is used instead of Uint32Array for performance reasons.
+ this.state = new Int32Array(8); // hash state
+ this.temp = new Int32Array(64); // temporary state
+ this.buffer = new Uint8Array(128); // buffer for data to hash
+ this.bufferLength = 0; // number of bytes in buffer
+ this.bytesHashed = 0; // number of total bytes hashed
+ this.finished = false; // indicates whether the hash was finalized
+ this.reset();
+ }
+ // Resets hash state making it possible
+ // to re-use this instance to hash other data.
+ reset() {
+ this.state[0] = 0x6a09e667;
+ this.state[1] = 0xbb67ae85;
+ this.state[2] = 0x3c6ef372;
+ this.state[3] = 0xa54ff53a;
+ this.state[4] = 0x510e527f;
+ this.state[5] = 0x9b05688c;
+ this.state[6] = 0x1f83d9ab;
+ this.state[7] = 0x5be0cd19;
+ this.bufferLength = 0;
+ this.bytesHashed = 0;
+ this.finished = false;
+ return this;
+ }
+ // Cleans internal buffers and re-initializes hash state.
+ clean() {
+ for (let i = 0; i < this.buffer.length; i++) {
+ this.buffer[i] = 0;
+ }
+ for (let i = 0; i < this.temp.length; i++) {
+ this.temp[i] = 0;
+ }
+ this.reset();
+ }
+ // Updates hash state with the given data.
+ //
+ // Optionally, length of the data can be specified to hash
+ // fewer bytes than data.length.
+ //
+ // Throws error when trying to update already finalized hash:
+ // instance must be reset to use it again.
+ update(data, dataLength = data.length) {
+ if (this.finished) {
+ throw new Error("SHA256: can't update because hash was finished.");
+ }
+ let dataPos = 0;
+ this.bytesHashed += dataLength;
+ if (this.bufferLength > 0) {
+ while (this.bufferLength < 64 && dataLength > 0) {
+ this.buffer[this.bufferLength++] = data[dataPos++];
+ dataLength--;
+ }
+ if (this.bufferLength === 64) {
+ hashBlocks(this.temp, this.state, this.buffer, 0, 64);
+ this.bufferLength = 0;
+ }
+ }
+ if (dataLength >= 64) {
+ dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);
+ dataLength %= 64;
+ }
+ while (dataLength > 0) {
+ this.buffer[this.bufferLength++] = data[dataPos++];
+ dataLength--;
+ }
+ return this;
+ }
+ // Finalizes hash state and puts hash into out.
+ //
+ // If hash was already finalized, puts the same value.
+ finish(out) {
+ if (!this.finished) {
+ const bytesHashed = this.bytesHashed;
+ const left = this.bufferLength;
+ const bitLenHi = (bytesHashed / 0x20000000) | 0;
+ const bitLenLo = bytesHashed << 3;
+ const padLength = bytesHashed % 64 < 56 ? 64 : 128;
+ this.buffer[left] = 0x80;
+ for (let i = left + 1; i < padLength - 8; i++) {
+ this.buffer[i] = 0;
+ }
+ this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;
+ this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;
+ this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;
+ this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;
+ this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;
+ this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;
+ this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;
+ this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;
+ hashBlocks(this.temp, this.state, this.buffer, 0, padLength);
+ this.finished = true;
+ }
+ for (let i = 0; i < 8; i++) {
+ out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;
+ out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
+ out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
+ out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
+ }
+ return this;
+ }
+ // Returns the final hash digest.
+ digest() {
+ const out = new Uint8Array(this.digestLength);
+ this.finish(out);
+ return out;
+ }
+ // Internal function for use in HMAC for optimization.
+ _saveState(out) {
+ for (let i = 0; i < this.state.length; i++) {
+ out[i] = this.state[i];
+ }
+ }
+ // Internal function for use in HMAC for optimization.
+ _restoreState(from, bytesHashed) {
+ for (let i = 0; i < this.state.length; i++) {
+ this.state[i] = from[i];
+ }
+ this.bytesHashed = bytesHashed;
+ this.finished = false;
+ this.bufferLength = 0;
+ }
+}
+// Returns SHA256 hash of data.
+function sha256(data) {
+ const h = new HashSha256().update(data);
+ const digest = h.digest();
+ h.clean();
+ return digest;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+function sha512(data) {
+ return hash$1(data);
+}
+function hmac(digest, blockSize, key, message) {
+ if (key.byteLength > blockSize) {
+ key = digest(key);
+ }
+ if (key.byteLength < blockSize) {
+ const k = key;
+ key = new Uint8Array(blockSize);
+ key.set(k, 0);
+ }
+ const okp = new Uint8Array(blockSize);
+ const ikp = new Uint8Array(blockSize);
+ for (let i = 0; i < blockSize; i++) {
+ ikp[i] = key[i] ^ 0x36;
+ okp[i] = key[i] ^ 0x5c;
+ }
+ const b1 = new Uint8Array(blockSize + message.byteLength);
+ b1.set(ikp, 0);
+ b1.set(message, blockSize);
+ const h0 = digest(b1);
+ const b2 = new Uint8Array(blockSize + h0.length);
+ b2.set(okp, 0);
+ b2.set(h0, blockSize);
+ return digest(b2);
+}
+function hmacSha512(key, message) {
+ return hmac(sha512, 128, key, message);
+}
+function hmacSha256(key, message) {
+ return hmac(sha256, 64, key, message);
+}
+/**
+ * HMAC-SHA512-SHA256 (see RFC 5869).
+ */
+function kdfKw(args) {
+ return kdf(args.outputLength, args.ikm, args.salt, args.info);
+}
+function kdf(outputLength, ikm, salt, info) {
+ salt = salt !== null && salt !== void 0 ? salt : new Uint8Array(64);
+ // extract
+ const prk = hmacSha512(salt, ikm);
+ info = info !== null && info !== void 0 ? info : new Uint8Array(0);
+ // expand
+ const N = Math.ceil(outputLength / 32);
+ const output = new Uint8Array(N * 32);
+ for (let i = 0; i < N; i++) {
+ let buf;
+ if (i == 0) {
+ buf = new Uint8Array(info.byteLength + 1);
+ buf.set(info, 0);
+ }
+ else {
+ buf = new Uint8Array(info.byteLength + 1 + 32);
+ for (let j = 0; j < 32; j++) {
+ buf[j] = output[(i - 1) * 32 + j];
+ }
+ buf.set(info, 32);
+ }
+ buf[buf.length - 1] = i + 1;
+ const chunk = hmacSha256(prk, buf);
+ output.set(chunk, i * 32);
+ }
+ return output.slice(0, outputLength);
+}
+
+function getDefaultExportFromCjs (x) {
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+}
+
+var BigInteger = {exports: {}};
+
+(function (module) {
+ var bigInt = (function (undefined$1) {
+
+ var BASE = 1e7,
+ LOG_BASE = 7,
+ MAX_INT = 9007199254740992,
+ MAX_INT_ARR = smallToArray(MAX_INT),
+ DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ var supportsNativeBigInt = typeof BigInt === "function";
+
+ function Integer(v, radix, alphabet, caseSensitive) {
+ if (typeof v === "undefined") return Integer[0];
+ if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
+ return parseValue(v);
+ }
+
+ function BigInteger(value, sign) {
+ this.value = value;
+ this.sign = sign;
+ this.isSmall = false;
+ }
+ BigInteger.prototype = Object.create(Integer.prototype);
+
+ function SmallInteger(value) {
+ this.value = value;
+ this.sign = value < 0;
+ this.isSmall = true;
+ }
+ SmallInteger.prototype = Object.create(Integer.prototype);
+
+ function NativeBigInt(value) {
+ this.value = value;
+ }
+ NativeBigInt.prototype = Object.create(Integer.prototype);
+
+ function isPrecise(n) {
+ return -MAX_INT < n && n < MAX_INT;
+ }
+
+ function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
+ if (n < 1e7)
+ return [n];
+ if (n < 1e14)
+ return [n % 1e7, Math.floor(n / 1e7)];
+ return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
+ }
+
+ function arrayToSmall(arr) { // If BASE changes this function may need to change
+ trim(arr);
+ var length = arr.length;
+ if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
+ switch (length) {
+ case 0: return 0;
+ case 1: return arr[0];
+ case 2: return arr[0] + arr[1] * BASE;
+ default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
+ }
+ }
+ return arr;
+ }
+
+ function trim(v) {
+ var i = v.length;
+ while (v[--i] === 0);
+ v.length = i + 1;
+ }
+
+ function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
+ var x = new Array(length);
+ var i = -1;
+ while (++i < length) {
+ x[i] = 0;
+ }
+ return x;
+ }
+
+ function truncate(n) {
+ if (n > 0) return Math.floor(n);
+ return Math.ceil(n);
+ }
+
+ function add(a, b) { // assumes a and b are arrays with a.length >= b.length
+ var l_a = a.length,
+ l_b = b.length,
+ r = new Array(l_a),
+ carry = 0,
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l_b; i++) {
+ sum = a[i] + b[i] + carry;
+ carry = sum >= base ? 1 : 0;
+ r[i] = sum - carry * base;
+ }
+ while (i < l_a) {
+ sum = a[i] + carry;
+ carry = sum === base ? 1 : 0;
+ r[i++] = sum - carry * base;
+ }
+ if (carry > 0) r.push(carry);
+ return r;
+ }
+
+ function addAny(a, b) {
+ if (a.length >= b.length) return add(a, b);
+ return add(b, a);
+ }
+
+ function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ sum, i;
+ for (i = 0; i < l; i++) {
+ sum = a[i] - base + carry;
+ carry = Math.floor(sum / base);
+ r[i] = sum - carry * base;
+ carry += 1;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ BigInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall) {
+ return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
+ }
+ return new BigInteger(addAny(a, b), this.sign);
+ };
+ BigInteger.prototype.plus = BigInteger.prototype.add;
+
+ SmallInteger.prototype.add = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.subtract(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ if (isPrecise(a + b)) return new SmallInteger(a + b);
+ b = smallToArray(Math.abs(b));
+ }
+ return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
+ };
+ SmallInteger.prototype.plus = SmallInteger.prototype.add;
+
+ NativeBigInt.prototype.add = function (v) {
+ return new NativeBigInt(this.value + parseValue(v).value);
+ };
+ NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
+
+ function subtract(a, b) { // assumes a and b are arrays with a >= b
+ var a_l = a.length,
+ b_l = b.length,
+ r = new Array(a_l),
+ borrow = 0,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < b_l; i++) {
+ difference = a[i] - borrow - b[i];
+ if (difference < 0) {
+ difference += base;
+ borrow = 1;
+ } else borrow = 0;
+ r[i] = difference;
+ }
+ for (i = b_l; i < a_l; i++) {
+ difference = a[i] - borrow;
+ if (difference < 0) difference += base;
+ else {
+ r[i++] = difference;
+ break;
+ }
+ r[i] = difference;
+ }
+ for (; i < a_l; i++) {
+ r[i] = a[i];
+ }
+ trim(r);
+ return r;
+ }
+
+ function subtractAny(a, b, sign) {
+ var value;
+ if (compareAbs(a, b) >= 0) {
+ value = subtract(a, b);
+ } else {
+ value = subtract(b, a);
+ sign = !sign;
+ }
+ value = arrayToSmall(value);
+ if (typeof value === "number") {
+ if (sign) value = -value;
+ return new SmallInteger(value);
+ }
+ return new BigInteger(value, sign);
+ }
+
+ function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
+ var l = a.length,
+ r = new Array(l),
+ carry = -b,
+ base = BASE,
+ i, difference;
+ for (i = 0; i < l; i++) {
+ difference = a[i] + carry;
+ carry = Math.floor(difference / base);
+ difference %= base;
+ r[i] = difference < 0 ? difference + base : difference;
+ }
+ r = arrayToSmall(r);
+ if (typeof r === "number") {
+ if (sign) r = -r;
+ return new SmallInteger(r);
+ } return new BigInteger(r, sign);
+ }
+
+ BigInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ if (this.sign !== n.sign) {
+ return this.add(n.negate());
+ }
+ var a = this.value, b = n.value;
+ if (n.isSmall)
+ return subtractSmall(a, Math.abs(b), this.sign);
+ return subtractAny(a, b, this.sign);
+ };
+ BigInteger.prototype.minus = BigInteger.prototype.subtract;
+
+ SmallInteger.prototype.subtract = function (v) {
+ var n = parseValue(v);
+ var a = this.value;
+ if (a < 0 !== n.sign) {
+ return this.add(n.negate());
+ }
+ var b = n.value;
+ if (n.isSmall) {
+ return new SmallInteger(a - b);
+ }
+ return subtractSmall(b, Math.abs(a), a >= 0);
+ };
+ SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
+
+ NativeBigInt.prototype.subtract = function (v) {
+ return new NativeBigInt(this.value - parseValue(v).value);
+ };
+ NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
+
+ BigInteger.prototype.negate = function () {
+ return new BigInteger(this.value, !this.sign);
+ };
+ SmallInteger.prototype.negate = function () {
+ var sign = this.sign;
+ var small = new SmallInteger(-this.value);
+ small.sign = !sign;
+ return small;
+ };
+ NativeBigInt.prototype.negate = function () {
+ return new NativeBigInt(-this.value);
+ };
+
+ BigInteger.prototype.abs = function () {
+ return new BigInteger(this.value, false);
+ };
+ SmallInteger.prototype.abs = function () {
+ return new SmallInteger(Math.abs(this.value));
+ };
+ NativeBigInt.prototype.abs = function () {
+ return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
+ };
+
+
+ function multiplyLong(a, b) {
+ var a_l = a.length,
+ b_l = b.length,
+ l = a_l + b_l,
+ r = createArray(l),
+ base = BASE,
+ product, carry, i, a_i, b_j;
+ for (i = 0; i < a_l; ++i) {
+ a_i = a[i];
+ for (var j = 0; j < b_l; ++j) {
+ b_j = b[j];
+ product = a_i * b_j + r[i + j];
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ r[i + j + 1] += carry;
+ }
+ }
+ trim(r);
+ return r;
+ }
+
+ function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
+ var l = a.length,
+ r = new Array(l),
+ base = BASE,
+ carry = 0,
+ product, i;
+ for (i = 0; i < l; i++) {
+ product = a[i] * b + carry;
+ carry = Math.floor(product / base);
+ r[i] = product - carry * base;
+ }
+ while (carry > 0) {
+ r[i++] = carry % base;
+ carry = Math.floor(carry / base);
+ }
+ return r;
+ }
+
+ function shiftLeft(x, n) {
+ var r = [];
+ while (n-- > 0) r.push(0);
+ return r.concat(x);
+ }
+
+ function multiplyKaratsuba(x, y) {
+ var n = Math.max(x.length, y.length);
+
+ if (n <= 30) return multiplyLong(x, y);
+ n = Math.ceil(n / 2);
+
+ var b = x.slice(n),
+ a = x.slice(0, n),
+ d = y.slice(n),
+ c = y.slice(0, n);
+
+ var ac = multiplyKaratsuba(a, c),
+ bd = multiplyKaratsuba(b, d),
+ abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
+
+ var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
+ trim(product);
+ return product;
+ }
+
+ // The following function is derived from a surface fit of a graph plotting the performance difference
+ // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
+ function useKaratsuba(l1, l2) {
+ return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
+ }
+
+ BigInteger.prototype.multiply = function (v) {
+ var n = parseValue(v),
+ a = this.value, b = n.value,
+ sign = this.sign !== n.sign,
+ abs;
+ if (n.isSmall) {
+ if (b === 0) return Integer[0];
+ if (b === 1) return this;
+ if (b === -1) return this.negate();
+ abs = Math.abs(b);
+ if (abs < BASE) {
+ return new BigInteger(multiplySmall(a, abs), sign);
+ }
+ b = smallToArray(abs);
+ }
+ if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
+ return new BigInteger(multiplyKaratsuba(a, b), sign);
+ return new BigInteger(multiplyLong(a, b), sign);
+ };
+
+ BigInteger.prototype.times = BigInteger.prototype.multiply;
+
+ function multiplySmallAndArray(a, b, sign) { // a >= 0
+ if (a < BASE) {
+ return new BigInteger(multiplySmall(b, a), sign);
+ }
+ return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
+ }
+ SmallInteger.prototype._multiplyBySmall = function (a) {
+ if (isPrecise(a.value * this.value)) {
+ return new SmallInteger(a.value * this.value);
+ }
+ return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
+ };
+ BigInteger.prototype._multiplyBySmall = function (a) {
+ if (a.value === 0) return Integer[0];
+ if (a.value === 1) return this;
+ if (a.value === -1) return this.negate();
+ return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
+ };
+ SmallInteger.prototype.multiply = function (v) {
+ return parseValue(v)._multiplyBySmall(this);
+ };
+ SmallInteger.prototype.times = SmallInteger.prototype.multiply;
+
+ NativeBigInt.prototype.multiply = function (v) {
+ return new NativeBigInt(this.value * parseValue(v).value);
+ };
+ NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
+
+ function square(a) {
+ //console.assert(2 * BASE * BASE < MAX_INT);
+ var l = a.length,
+ r = createArray(l + l),
+ base = BASE,
+ product, carry, i, a_i, a_j;
+ for (i = 0; i < l; i++) {
+ a_i = a[i];
+ carry = 0 - a_i * a_i;
+ for (var j = i; j < l; j++) {
+ a_j = a[j];
+ product = 2 * (a_i * a_j) + r[i + j] + carry;
+ carry = Math.floor(product / base);
+ r[i + j] = product - carry * base;
+ }
+ r[i + l] = carry;
+ }
+ trim(r);
+ return r;
+ }
+
+ BigInteger.prototype.square = function () {
+ return new BigInteger(square(this.value), false);
+ };
+
+ SmallInteger.prototype.square = function () {
+ var value = this.value * this.value;
+ if (isPrecise(value)) return new SmallInteger(value);
+ return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
+ };
+
+ NativeBigInt.prototype.square = function (v) {
+ return new NativeBigInt(this.value * this.value);
+ };
+
+ function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ base = BASE,
+ result = createArray(b.length),
+ divisorMostSignificantDigit = b[b_l - 1],
+ // normalization
+ lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
+ remainder = multiplySmall(a, lambda),
+ divisor = multiplySmall(b, lambda),
+ quotientDigit, shift, carry, borrow, i, l, q;
+ if (remainder.length <= a_l) remainder.push(0);
+ divisor.push(0);
+ divisorMostSignificantDigit = divisor[b_l - 1];
+ for (shift = a_l - b_l; shift >= 0; shift--) {
+ quotientDigit = base - 1;
+ if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
+ quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
+ }
+ // quotientDigit <= base - 1
+ carry = 0;
+ borrow = 0;
+ l = divisor.length;
+ for (i = 0; i < l; i++) {
+ carry += quotientDigit * divisor[i];
+ q = Math.floor(carry / base);
+ borrow += remainder[shift + i] - (carry - q * base);
+ carry = q;
+ if (borrow < 0) {
+ remainder[shift + i] = borrow + base;
+ borrow = -1;
+ } else {
+ remainder[shift + i] = borrow;
+ borrow = 0;
+ }
+ }
+ while (borrow !== 0) {
+ quotientDigit -= 1;
+ carry = 0;
+ for (i = 0; i < l; i++) {
+ carry += remainder[shift + i] - base + divisor[i];
+ if (carry < 0) {
+ remainder[shift + i] = carry + base;
+ carry = 0;
+ } else {
+ remainder[shift + i] = carry;
+ carry = 1;
+ }
+ }
+ borrow += carry;
+ }
+ result[shift] = quotientDigit;
+ }
+ // denormalization
+ remainder = divModSmall(remainder, lambda)[0];
+ return [arrayToSmall(result), arrayToSmall(remainder)];
+ }
+
+ function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
+ // Performs faster than divMod1 on larger input sizes.
+ var a_l = a.length,
+ b_l = b.length,
+ result = [],
+ part = [],
+ base = BASE,
+ guess, xlen, highx, highy, check;
+ while (a_l) {
+ part.unshift(a[--a_l]);
+ trim(part);
+ if (compareAbs(part, b) < 0) {
+ result.push(0);
+ continue;
+ }
+ xlen = part.length;
+ highx = part[xlen - 1] * base + part[xlen - 2];
+ highy = b[b_l - 1] * base + b[b_l - 2];
+ if (xlen > b_l) {
+ highx = (highx + 1) * base;
+ }
+ guess = Math.ceil(highx / highy);
+ do {
+ check = multiplySmall(b, guess);
+ if (compareAbs(check, part) <= 0) break;
+ guess--;
+ } while (guess);
+ result.push(guess);
+ part = subtract(part, check);
+ }
+ result.reverse();
+ return [arrayToSmall(result), arrayToSmall(part)];
+ }
+
+ function divModSmall(value, lambda) {
+ var length = value.length,
+ quotient = createArray(length),
+ base = BASE,
+ i, q, remainder, divisor;
+ remainder = 0;
+ for (i = length - 1; i >= 0; --i) {
+ divisor = remainder * base + value[i];
+ q = truncate(divisor / lambda);
+ remainder = divisor - q * lambda;
+ quotient[i] = q | 0;
+ }
+ return [quotient, remainder | 0];
+ }
+
+ function divModAny(self, v) {
+ var value, n = parseValue(v);
+ if (supportsNativeBigInt) {
+ return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
+ }
+ var a = self.value, b = n.value;
+ var quotient;
+ if (b === 0) throw new Error("Cannot divide by zero");
+ if (self.isSmall) {
+ if (n.isSmall) {
+ return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
+ }
+ return [Integer[0], self];
+ }
+ if (n.isSmall) {
+ if (b === 1) return [self, Integer[0]];
+ if (b == -1) return [self.negate(), Integer[0]];
+ var abs = Math.abs(b);
+ if (abs < BASE) {
+ value = divModSmall(a, abs);
+ quotient = arrayToSmall(value[0]);
+ var remainder = value[1];
+ if (self.sign) remainder = -remainder;
+ if (typeof quotient === "number") {
+ if (self.sign !== n.sign) quotient = -quotient;
+ return [new SmallInteger(quotient), new SmallInteger(remainder)];
+ }
+ return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
+ }
+ b = smallToArray(abs);
+ }
+ var comparison = compareAbs(a, b);
+ if (comparison === -1) return [Integer[0], self];
+ if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
+
+ // divMod1 is faster on smaller input sizes
+ if (a.length + b.length <= 200)
+ value = divMod1(a, b);
+ else value = divMod2(a, b);
+
+ quotient = value[0];
+ var qSign = self.sign !== n.sign,
+ mod = value[1],
+ mSign = self.sign;
+ if (typeof quotient === "number") {
+ if (qSign) quotient = -quotient;
+ quotient = new SmallInteger(quotient);
+ } else quotient = new BigInteger(quotient, qSign);
+ if (typeof mod === "number") {
+ if (mSign) mod = -mod;
+ mod = new SmallInteger(mod);
+ } else mod = new BigInteger(mod, mSign);
+ return [quotient, mod];
+ }
+
+ BigInteger.prototype.divmod = function (v) {
+ var result = divModAny(this, v);
+ return {
+ quotient: result[0],
+ remainder: result[1]
+ };
+ };
+ NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
+
+
+ BigInteger.prototype.divide = function (v) {
+ return divModAny(this, v)[0];
+ };
+ NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
+ return new NativeBigInt(this.value / parseValue(v).value);
+ };
+ SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
+
+ BigInteger.prototype.mod = function (v) {
+ return divModAny(this, v)[1];
+ };
+ NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
+ return new NativeBigInt(this.value % parseValue(v).value);
+ };
+ SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
+
+ BigInteger.prototype.pow = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value,
+ value, x, y;
+ if (b === 0) return Integer[1];
+ if (a === 0) return Integer[0];
+ if (a === 1) return Integer[1];
+ if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.sign) {
+ return Integer[0];
+ }
+ if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
+ if (this.isSmall) {
+ if (isPrecise(value = Math.pow(a, b)))
+ return new SmallInteger(truncate(value));
+ }
+ x = this;
+ y = Integer[1];
+ while (true) {
+ if (b & 1 === 1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === 0) break;
+ b /= 2;
+ x = x.square();
+ }
+ return y;
+ };
+ SmallInteger.prototype.pow = BigInteger.prototype.pow;
+
+ NativeBigInt.prototype.pow = function (v) {
+ var n = parseValue(v);
+ var a = this.value, b = n.value;
+ var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
+ if (b === _0) return Integer[1];
+ if (a === _0) return Integer[0];
+ if (a === _1) return Integer[1];
+ if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
+ if (n.isNegative()) return new NativeBigInt(_0);
+ var x = this;
+ var y = Integer[1];
+ while (true) {
+ if ((b & _1) === _1) {
+ y = y.times(x);
+ --b;
+ }
+ if (b === _0) break;
+ b /= _2;
+ x = x.square();
+ }
+ return y;
+ };
+
+ BigInteger.prototype.modPow = function (exp, mod) {
+ exp = parseValue(exp);
+ mod = parseValue(mod);
+ if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
+ var r = Integer[1],
+ base = this.mod(mod);
+ if (exp.isNegative()) {
+ exp = exp.multiply(Integer[-1]);
+ base = base.modInv(mod);
+ }
+ while (exp.isPositive()) {
+ if (base.isZero()) return Integer[0];
+ if (exp.isOdd()) r = r.multiply(base).mod(mod);
+ exp = exp.divide(2);
+ base = base.square().mod(mod);
+ }
+ return r;
+ };
+ NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
+
+ function compareAbs(a, b) {
+ if (a.length !== b.length) {
+ return a.length > b.length ? 1 : -1;
+ }
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
+ }
+ return 0;
+ }
+
+ BigInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) return 1;
+ return compareAbs(a, b);
+ };
+ SmallInteger.prototype.compareAbs = function (v) {
+ var n = parseValue(v),
+ a = Math.abs(this.value),
+ b = n.value;
+ if (n.isSmall) {
+ b = Math.abs(b);
+ return a === b ? 0 : a > b ? 1 : -1;
+ }
+ return -1;
+ };
+ NativeBigInt.prototype.compareAbs = function (v) {
+ var a = this.value;
+ var b = parseValue(v).value;
+ a = a >= 0 ? a : -a;
+ b = b >= 0 ? b : -b;
+ return a === b ? 0 : a > b ? 1 : -1;
+ };
+
+ BigInteger.prototype.compare = function (v) {
+ // See discussion about comparison with Infinity:
+ // https://github.com/peterolson/BigInteger.js/issues/61
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (this.sign !== n.sign) {
+ return n.sign ? 1 : -1;
+ }
+ if (n.isSmall) {
+ return this.sign ? -1 : 1;
+ }
+ return compareAbs(a, b) * (this.sign ? -1 : 1);
+ };
+ BigInteger.prototype.compareTo = BigInteger.prototype.compare;
+
+ SmallInteger.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+
+ var n = parseValue(v),
+ a = this.value,
+ b = n.value;
+ if (n.isSmall) {
+ return a == b ? 0 : a > b ? 1 : -1;
+ }
+ if (a < 0 !== n.sign) {
+ return a < 0 ? -1 : 1;
+ }
+ return a < 0 ? 1 : -1;
+ };
+ SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
+
+ NativeBigInt.prototype.compare = function (v) {
+ if (v === Infinity) {
+ return -1;
+ }
+ if (v === -Infinity) {
+ return 1;
+ }
+ var a = this.value;
+ var b = parseValue(v).value;
+ return a === b ? 0 : a > b ? 1 : -1;
+ };
+ NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
+
+ BigInteger.prototype.equals = function (v) {
+ return this.compare(v) === 0;
+ };
+ NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
+
+ BigInteger.prototype.notEquals = function (v) {
+ return this.compare(v) !== 0;
+ };
+ NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
+
+ BigInteger.prototype.greater = function (v) {
+ return this.compare(v) > 0;
+ };
+ NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
+
+ BigInteger.prototype.lesser = function (v) {
+ return this.compare(v) < 0;
+ };
+ NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
+
+ BigInteger.prototype.greaterOrEquals = function (v) {
+ return this.compare(v) >= 0;
+ };
+ NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
+
+ BigInteger.prototype.lesserOrEquals = function (v) {
+ return this.compare(v) <= 0;
+ };
+ NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
+
+ BigInteger.prototype.isEven = function () {
+ return (this.value[0] & 1) === 0;
+ };
+ SmallInteger.prototype.isEven = function () {
+ return (this.value & 1) === 0;
+ };
+ NativeBigInt.prototype.isEven = function () {
+ return (this.value & BigInt(1)) === BigInt(0);
+ };
+
+ BigInteger.prototype.isOdd = function () {
+ return (this.value[0] & 1) === 1;
+ };
+ SmallInteger.prototype.isOdd = function () {
+ return (this.value & 1) === 1;
+ };
+ NativeBigInt.prototype.isOdd = function () {
+ return (this.value & BigInt(1)) === BigInt(1);
+ };
+
+ BigInteger.prototype.isPositive = function () {
+ return !this.sign;
+ };
+ SmallInteger.prototype.isPositive = function () {
+ return this.value > 0;
+ };
+ NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
+
+ BigInteger.prototype.isNegative = function () {
+ return this.sign;
+ };
+ SmallInteger.prototype.isNegative = function () {
+ return this.value < 0;
+ };
+ NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
+
+ BigInteger.prototype.isUnit = function () {
+ return false;
+ };
+ SmallInteger.prototype.isUnit = function () {
+ return Math.abs(this.value) === 1;
+ };
+ NativeBigInt.prototype.isUnit = function () {
+ return this.abs().value === BigInt(1);
+ };
+
+ BigInteger.prototype.isZero = function () {
+ return false;
+ };
+ SmallInteger.prototype.isZero = function () {
+ return this.value === 0;
+ };
+ NativeBigInt.prototype.isZero = function () {
+ return this.value === BigInt(0);
+ };
+
+ BigInteger.prototype.isDivisibleBy = function (v) {
+ var n = parseValue(v);
+ if (n.isZero()) return false;
+ if (n.isUnit()) return true;
+ if (n.compareAbs(2) === 0) return this.isEven();
+ return this.mod(n).isZero();
+ };
+ NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
+
+ function isBasicPrime(v) {
+ var n = v.abs();
+ if (n.isUnit()) return false;
+ if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
+ if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
+ if (n.lesser(49)) return true;
+ // we don't know if it's prime: let the other functions figure it out
+ }
+
+ function millerRabinTest(n, a) {
+ var nPrev = n.prev(),
+ b = nPrev,
+ r = 0,
+ d, i, x;
+ while (b.isEven()) b = b.divide(2), r++;
+ next: for (i = 0; i < a.length; i++) {
+ if (n.lesser(a[i])) continue;
+ x = bigInt(a[i]).modPow(b, n);
+ if (x.isUnit() || x.equals(nPrev)) continue;
+ for (d = r - 1; d != 0; d--) {
+ x = x.square().mod(n);
+ if (x.isUnit()) return false;
+ if (x.equals(nPrev)) continue next;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
+ BigInteger.prototype.isPrime = function (strict) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined$1) return isPrime;
+ var n = this.abs();
+ var bits = n.bitLength();
+ if (bits <= 64)
+ return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
+ var logN = Math.log(2) * bits.toJSNumber();
+ var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt(i + 2));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
+
+ BigInteger.prototype.isProbablePrime = function (iterations, rng) {
+ var isPrime = isBasicPrime(this);
+ if (isPrime !== undefined$1) return isPrime;
+ var n = this.abs();
+ var t = iterations === undefined$1 ? 5 : iterations;
+ for (var a = [], i = 0; i < t; i++) {
+ a.push(bigInt.randBetween(2, n.minus(2), rng));
+ }
+ return millerRabinTest(n, a);
+ };
+ NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
+
+ BigInteger.prototype.modInv = function (n) {
+ var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
+ while (!newR.isZero()) {
+ q = r.divide(newR);
+ lastT = t;
+ lastR = r;
+ t = newT;
+ r = newR;
+ newT = lastT.subtract(q.multiply(newT));
+ newR = lastR.subtract(q.multiply(newR));
+ }
+ if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
+ if (t.compare(0) === -1) {
+ t = t.add(n);
+ }
+ if (this.isNegative()) {
+ return t.negate();
+ }
+ return t;
+ };
+
+ NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
+
+ BigInteger.prototype.next = function () {
+ var value = this.value;
+ if (this.sign) {
+ return subtractSmall(value, 1, this.sign);
+ }
+ return new BigInteger(addSmall(value, 1), this.sign);
+ };
+ SmallInteger.prototype.next = function () {
+ var value = this.value;
+ if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
+ return new BigInteger(MAX_INT_ARR, false);
+ };
+ NativeBigInt.prototype.next = function () {
+ return new NativeBigInt(this.value + BigInt(1));
+ };
+
+ BigInteger.prototype.prev = function () {
+ var value = this.value;
+ if (this.sign) {
+ return new BigInteger(addSmall(value, 1), true);
+ }
+ return subtractSmall(value, 1, this.sign);
+ };
+ SmallInteger.prototype.prev = function () {
+ var value = this.value;
+ if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
+ return new BigInteger(MAX_INT_ARR, true);
+ };
+ NativeBigInt.prototype.prev = function () {
+ return new NativeBigInt(this.value - BigInt(1));
+ };
+
+ var powersOfTwo = [1];
+ while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
+ var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
+
+ function shift_isSmall(n) {
+ return Math.abs(n) <= BASE;
+ }
+
+ BigInteger.prototype.shiftLeft = function (v) {
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftRight(-n);
+ var result = this;
+ if (result.isZero()) return result;
+ while (n >= powers2Length) {
+ result = result.multiply(highestPower2);
+ n -= powers2Length - 1;
+ }
+ return result.multiply(powersOfTwo[n]);
+ };
+ NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
+
+ BigInteger.prototype.shiftRight = function (v) {
+ var remQuo;
+ var n = parseValue(v).toJSNumber();
+ if (!shift_isSmall(n)) {
+ throw new Error(String(n) + " is too large for shifting.");
+ }
+ if (n < 0) return this.shiftLeft(-n);
+ var result = this;
+ while (n >= powers2Length) {
+ if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
+ remQuo = divModAny(result, highestPower2);
+ result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ n -= powers2Length - 1;
+ }
+ remQuo = divModAny(result, powersOfTwo[n]);
+ return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
+ };
+ NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
+
+ function bitwise(x, y, fn) {
+ y = parseValue(y);
+ var xSign = x.isNegative(), ySign = y.isNegative();
+ var xRem = xSign ? x.not() : x,
+ yRem = ySign ? y.not() : y;
+ var xDigit = 0, yDigit = 0;
+ var xDivMod = null, yDivMod = null;
+ var result = [];
+ while (!xRem.isZero() || !yRem.isZero()) {
+ xDivMod = divModAny(xRem, highestPower2);
+ xDigit = xDivMod[1].toJSNumber();
+ if (xSign) {
+ xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
+ }
+
+ yDivMod = divModAny(yRem, highestPower2);
+ yDigit = yDivMod[1].toJSNumber();
+ if (ySign) {
+ yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
+ }
+
+ xRem = xDivMod[0];
+ yRem = yDivMod[0];
+ result.push(fn(xDigit, yDigit));
+ }
+ var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
+ for (var i = result.length - 1; i >= 0; i -= 1) {
+ sum = sum.multiply(highestPower2).add(bigInt(result[i]));
+ }
+ return sum;
+ }
+
+ BigInteger.prototype.not = function () {
+ return this.negate().prev();
+ };
+ NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
+
+ BigInteger.prototype.and = function (n) {
+ return bitwise(this, n, function (a, b) { return a & b; });
+ };
+ NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
+
+ BigInteger.prototype.or = function (n) {
+ return bitwise(this, n, function (a, b) { return a | b; });
+ };
+ NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
+
+ BigInteger.prototype.xor = function (n) {
+ return bitwise(this, n, function (a, b) { return a ^ b; });
+ };
+ NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
+
+ var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
+ function roughLOB(n) { // get lowestOneBit (rough)
+ // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
+ // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
+ var v = n.value,
+ x = typeof v === "number" ? v | LOBMASK_I :
+ typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
+ v[0] + v[1] * BASE | LOBMASK_BI;
+ return x & -x;
+ }
+
+ function integerLogarithm(value, base) {
+ if (base.compareTo(value) <= 0) {
+ var tmp = integerLogarithm(value, base.square(base));
+ var p = tmp.p;
+ var e = tmp.e;
+ var t = p.multiply(base);
+ return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
+ }
+ return { p: bigInt(1), e: 0 };
+ }
+
+ BigInteger.prototype.bitLength = function () {
+ var n = this;
+ if (n.compareTo(bigInt(0)) < 0) {
+ n = n.negate().subtract(bigInt(1));
+ }
+ if (n.compareTo(bigInt(0)) === 0) {
+ return bigInt(0);
+ }
+ return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
+ };
+ NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
+
+ function max(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.greater(b) ? a : b;
+ }
+ function min(a, b) {
+ a = parseValue(a);
+ b = parseValue(b);
+ return a.lesser(b) ? a : b;
+ }
+ function gcd(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ if (a.equals(b)) return a;
+ if (a.isZero()) return b;
+ if (b.isZero()) return a;
+ var c = Integer[1], d, t;
+ while (a.isEven() && b.isEven()) {
+ d = min(roughLOB(a), roughLOB(b));
+ a = a.divide(d);
+ b = b.divide(d);
+ c = c.multiply(d);
+ }
+ while (a.isEven()) {
+ a = a.divide(roughLOB(a));
+ }
+ do {
+ while (b.isEven()) {
+ b = b.divide(roughLOB(b));
+ }
+ if (a.greater(b)) {
+ t = b; b = a; a = t;
+ }
+ b = b.subtract(a);
+ } while (!b.isZero());
+ return c.isUnit() ? a : a.multiply(c);
+ }
+ function lcm(a, b) {
+ a = parseValue(a).abs();
+ b = parseValue(b).abs();
+ return a.divide(gcd(a, b)).multiply(b);
+ }
+ function randBetween(a, b, rng) {
+ a = parseValue(a);
+ b = parseValue(b);
+ var usedRNG = rng || Math.random;
+ var low = min(a, b), high = max(a, b);
+ var range = high.subtract(low).add(1);
+ if (range.isSmall) return low.add(Math.floor(usedRNG() * range));
+ var digits = toBase(range, BASE).value;
+ var result = [], restricted = true;
+ for (var i = 0; i < digits.length; i++) {
+ var top = restricted ? digits[i] + (i + 1 < digits.length ? digits[i + 1] / BASE : 0) : BASE;
+ var digit = truncate(usedRNG() * top);
+ result.push(digit);
+ if (digit < digits[i]) restricted = false;
+ }
+ return low.add(Integer.fromArray(result, BASE, false));
+ }
+
+ var parseBase = function (text, base, alphabet, caseSensitive) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ text = String(text);
+ if (!caseSensitive) {
+ text = text.toLowerCase();
+ alphabet = alphabet.toLowerCase();
+ }
+ var length = text.length;
+ var i;
+ var absBase = Math.abs(base);
+ var alphabetValues = {};
+ for (i = 0; i < alphabet.length; i++) {
+ alphabetValues[alphabet[i]] = i;
+ }
+ for (i = 0; i < length; i++) {
+ var c = text[i];
+ if (c === "-") continue;
+ if (c in alphabetValues) {
+ if (alphabetValues[c] >= absBase) {
+ if (c === "1" && absBase === 1) continue;
+ throw new Error(c + " is not a valid digit in base " + base + ".");
+ }
+ }
+ }
+ base = parseValue(base);
+ var digits = [];
+ var isNegative = text[0] === "-";
+ for (i = isNegative ? 1 : 0; i < text.length; i++) {
+ var c = text[i];
+ if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
+ else if (c === "<") {
+ var start = i;
+ do { i++; } while (text[i] !== ">" && i < text.length);
+ digits.push(parseValue(text.slice(start + 1, i)));
+ }
+ else throw new Error(c + " is not a valid character");
+ }
+ return parseBaseFromArray(digits, base, isNegative);
+ };
+
+ function parseBaseFromArray(digits, base, isNegative) {
+ var val = Integer[0], pow = Integer[1], i;
+ for (i = digits.length - 1; i >= 0; i--) {
+ val = val.add(digits[i].times(pow));
+ pow = pow.times(base);
+ }
+ return isNegative ? val.negate() : val;
+ }
+
+ function stringify(digit, alphabet) {
+ alphabet = alphabet || DEFAULT_ALPHABET;
+ if (digit < alphabet.length) {
+ return alphabet[digit];
+ }
+ return "<" + digit + ">";
+ }
+
+ function toBase(n, base) {
+ base = bigInt(base);
+ if (base.isZero()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ throw new Error("Cannot convert nonzero numbers to base 0.");
+ }
+ if (base.equals(-1)) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+ if (n.isNegative())
+ return {
+ value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
+ .map(Array.prototype.valueOf, [1, 0])
+ ),
+ isNegative: false
+ };
+
+ var arr = Array.apply(null, Array(n.toJSNumber() - 1))
+ .map(Array.prototype.valueOf, [0, 1]);
+ arr.unshift([1]);
+ return {
+ value: [].concat.apply([], arr),
+ isNegative: false
+ };
+ }
+
+ var neg = false;
+ if (n.isNegative() && base.isPositive()) {
+ neg = true;
+ n = n.abs();
+ }
+ if (base.isUnit()) {
+ if (n.isZero()) return { value: [0], isNegative: false };
+
+ return {
+ value: Array.apply(null, Array(n.toJSNumber()))
+ .map(Number.prototype.valueOf, 1),
+ isNegative: neg
+ };
+ }
+ var out = [];
+ var left = n, divmod;
+ while (left.isNegative() || left.compareAbs(base) >= 0) {
+ divmod = left.divmod(base);
+ left = divmod.quotient;
+ var digit = divmod.remainder;
+ if (digit.isNegative()) {
+ digit = base.minus(digit).abs();
+ left = left.next();
+ }
+ out.push(digit.toJSNumber());
+ }
+ out.push(left.toJSNumber());
+ return { value: out.reverse(), isNegative: neg };
+ }
+
+ function toBaseString(n, base, alphabet) {
+ var arr = toBase(n, base);
+ return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
+ return stringify(x, alphabet);
+ }).join('');
+ }
+
+ BigInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ SmallInteger.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ NativeBigInt.prototype.toArray = function (radix) {
+ return toBase(this, radix);
+ };
+
+ BigInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined$1) radix = 10;
+ if (radix !== 10) return toBaseString(this, radix, alphabet);
+ var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
+ while (--l >= 0) {
+ digit = String(v[l]);
+ str += zeros.slice(digit.length) + digit;
+ }
+ var sign = this.sign ? "-" : "";
+ return sign + str;
+ };
+
+ SmallInteger.prototype.toString = function (radix, alphabet) {
+ if (radix === undefined$1) radix = 10;
+ if (radix != 10) return toBaseString(this, radix, alphabet);
+ return String(this.value);
+ };
+
+ NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
+
+ NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); };
+
+ BigInteger.prototype.valueOf = function () {
+ return parseInt(this.toString(), 10);
+ };
+ BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
+
+ SmallInteger.prototype.valueOf = function () {
+ return this.value;
+ };
+ SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
+ NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
+ return parseInt(this.toString(), 10);
+ };
+
+ function parseStringValue(v) {
+ if (isPrecise(+v)) {
+ var x = +v;
+ if (x === truncate(x))
+ return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
+ throw new Error("Invalid integer: " + v);
+ }
+ var sign = v[0] === "-";
+ if (sign) v = v.slice(1);
+ var split = v.split(/e/i);
+ if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
+ if (split.length === 2) {
+ var exp = split[1];
+ if (exp[0] === "+") exp = exp.slice(1);
+ exp = +exp;
+ if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
+ var text = split[0];
+ var decimalPlace = text.indexOf(".");
+ if (decimalPlace >= 0) {
+ exp -= text.length - decimalPlace - 1;
+ text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
+ }
+ if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
+ text += (new Array(exp + 1)).join("0");
+ v = text;
+ }
+ var isValid = /^([0-9][0-9]*)$/.test(v);
+ if (!isValid) throw new Error("Invalid integer: " + v);
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(sign ? "-" + v : v));
+ }
+ var r = [], max = v.length, l = LOG_BASE, min = max - l;
+ while (max > 0) {
+ r.push(+v.slice(min, max));
+ min -= l;
+ if (min < 0) min = 0;
+ max -= l;
+ }
+ trim(r);
+ return new BigInteger(r, sign);
+ }
+
+ function parseNumberValue(v) {
+ if (supportsNativeBigInt) {
+ return new NativeBigInt(BigInt(v));
+ }
+ if (isPrecise(v)) {
+ if (v !== truncate(v)) throw new Error(v + " is not an integer.");
+ return new SmallInteger(v);
+ }
+ return parseStringValue(v.toString());
+ }
+
+ function parseValue(v) {
+ if (typeof v === "number") {
+ return parseNumberValue(v);
+ }
+ if (typeof v === "string") {
+ return parseStringValue(v);
+ }
+ if (typeof v === "bigint") {
+ return new NativeBigInt(v);
+ }
+ return v;
+ }
+ // Pre-define numbers in range [-999,999]
+ for (var i = 0; i < 1000; i++) {
+ Integer[i] = parseValue(i);
+ if (i > 0) Integer[-i] = parseValue(-i);
+ }
+ // Backwards compatibility
+ Integer.one = Integer[1];
+ Integer.zero = Integer[0];
+ Integer.minusOne = Integer[-1];
+ Integer.max = max;
+ Integer.min = min;
+ Integer.gcd = gcd;
+ Integer.lcm = lcm;
+ Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
+ Integer.randBetween = randBetween;
+
+ Integer.fromArray = function (digits, base, isNegative) {
+ return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
+ };
+
+ return Integer;
+ })();
+
+ // Node.js check
+ if (module.hasOwnProperty("exports")) {
+ module.exports = bigInt;
+ }
+} (BigInteger));
+
+var bigint = BigInteger.exports;
+
+/*
+ This file is part of GNU Taler
+ (C) 2017-2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var TalerProtocolTimestamp;
+(function (TalerProtocolTimestamp) {
+ function now() {
+ return AbsoluteTime.toTimestamp(AbsoluteTime.now());
+ }
+ TalerProtocolTimestamp.now = now;
+ function zero() {
+ return {
+ t_s: 0,
+ };
+ }
+ TalerProtocolTimestamp.zero = zero;
+ function never() {
+ return {
+ t_s: "never",
+ };
+ }
+ TalerProtocolTimestamp.never = never;
+ function fromSeconds(s) {
+ return {
+ t_s: s,
+ };
+ }
+ TalerProtocolTimestamp.fromSeconds = fromSeconds;
+ function min(t1, t2) {
+ if (t1.t_s === "never") {
+ return { t_s: t2.t_s };
+ }
+ if (t2.t_s === "never") {
+ return { t_s: t2.t_s };
+ }
+ return { t_s: Math.min(t1.t_s, t2.t_s) };
+ }
+ TalerProtocolTimestamp.min = min;
+})(TalerProtocolTimestamp || (TalerProtocolTimestamp = {}));
+let timeshift = 0;
+var Duration;
+(function (Duration) {
+ function getRemaining(deadline, now = AbsoluteTime.now()) {
+ if (deadline.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ if (now.t_ms === "never") {
+ throw Error("invalid argument for 'now'");
+ }
+ if (deadline.t_ms < now.t_ms) {
+ return { d_ms: 0 };
+ }
+ return { d_ms: deadline.t_ms - now.t_ms };
+ }
+ Duration.getRemaining = getRemaining;
+ function max(d1, d2) {
+ return durationMax(d1, d2);
+ }
+ Duration.max = max;
+ function min(d1, d2) {
+ return durationMin(d1, d2);
+ }
+ Duration.min = min;
+ function multiply(d1, n) {
+ return durationMul(d1, n);
+ }
+ Duration.multiply = multiply;
+ function toIntegerYears(d) {
+ if (typeof d.d_ms !== "number") {
+ throw Error("infinite duration");
+ }
+ return Math.ceil(d.d_ms / 1000 / 60 / 60 / 24 / 365);
+ }
+ Duration.toIntegerYears = toIntegerYears;
+ Duration.fromSpec = durationFromSpec;
+ function getForever() {
+ return { d_ms: "forever" };
+ }
+ Duration.getForever = getForever;
+ function getZero() {
+ return { d_ms: 0 };
+ }
+ Duration.getZero = getZero;
+ function fromTalerProtocolDuration(d) {
+ if (d.d_us === "forever") {
+ return {
+ d_ms: "forever",
+ };
+ }
+ return {
+ d_ms: d.d_us / 1000,
+ };
+ }
+ Duration.fromTalerProtocolDuration = fromTalerProtocolDuration;
+ function toTalerProtocolDuration(d) {
+ if (d.d_ms === "forever") {
+ return {
+ d_us: "forever",
+ };
+ }
+ return {
+ d_us: d.d_ms * 1000,
+ };
+ }
+ Duration.toTalerProtocolDuration = toTalerProtocolDuration;
+ function clamp(args) {
+ return durationMax(durationMin(args.value, args.upper), args.lower);
+ }
+ Duration.clamp = clamp;
+})(Duration || (Duration = {}));
+var AbsoluteTime;
+(function (AbsoluteTime) {
+ function now() {
+ return {
+ t_ms: new Date().getTime() + timeshift,
+ };
+ }
+ AbsoluteTime.now = now;
+ function never() {
+ return {
+ t_ms: "never",
+ };
+ }
+ AbsoluteTime.never = never;
+ function cmp(t1, t2) {
+ if (t1.t_ms === "never") {
+ if (t2.t_ms === "never") {
+ return 0;
+ }
+ return 1;
+ }
+ if (t2.t_ms === "never") {
+ return -1;
+ }
+ if (t1.t_ms == t2.t_ms) {
+ return 0;
+ }
+ if (t1.t_ms > t2.t_ms) {
+ return 1;
+ }
+ return -1;
+ }
+ AbsoluteTime.cmp = cmp;
+ function min(t1, t2) {
+ if (t1.t_ms === "never") {
+ return { t_ms: t2.t_ms };
+ }
+ if (t2.t_ms === "never") {
+ return { t_ms: t2.t_ms };
+ }
+ return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
+ }
+ AbsoluteTime.min = min;
+ function max(t1, t2) {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ if (t2.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ return { t_ms: Math.max(t1.t_ms, t2.t_ms) };
+ }
+ AbsoluteTime.max = max;
+ function difference(t1, t2) {
+ if (t1.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ if (t2.t_ms === "never") {
+ return { d_ms: "forever" };
+ }
+ return { d_ms: Math.abs(t1.t_ms - t2.t_ms) };
+ }
+ AbsoluteTime.difference = difference;
+ function isExpired(t) {
+ return cmp(t, now()) <= 0;
+ }
+ AbsoluteTime.isExpired = isExpired;
+ function fromTimestamp(t) {
+ if (t.t_s === "never") {
+ return { t_ms: "never" };
+ }
+ return {
+ t_ms: t.t_s * 1000,
+ };
+ }
+ AbsoluteTime.fromTimestamp = fromTimestamp;
+ function toTimestamp(at) {
+ if (at.t_ms === "never") {
+ return { t_s: "never" };
+ }
+ return {
+ t_s: Math.floor(at.t_ms / 1000),
+ };
+ }
+ AbsoluteTime.toTimestamp = toTimestamp;
+ function isBetween(t, start, end) {
+ if (cmp(t, start) < 0) {
+ return false;
+ }
+ if (cmp(t, end) > 0) {
+ return false;
+ }
+ return true;
+ }
+ AbsoluteTime.isBetween = isBetween;
+ function toIsoString(t) {
+ if (t.t_ms === "never") {
+ return "<never>";
+ }
+ else {
+ return new Date(t.t_ms).toISOString();
+ }
+ }
+ AbsoluteTime.toIsoString = toIsoString;
+ function addDuration(t1, d) {
+ if (t1.t_ms === "never" || d.d_ms === "forever") {
+ return { t_ms: "never" };
+ }
+ return { t_ms: t1.t_ms + d.d_ms };
+ }
+ AbsoluteTime.addDuration = addDuration;
+ function subtractDuraction(t1, d) {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ if (d.d_ms === "forever") {
+ return { t_ms: 0 };
+ }
+ return { t_ms: Math.max(0, t1.t_ms - d.d_ms) };
+ }
+ AbsoluteTime.subtractDuraction = subtractDuraction;
+ function stringify(t) {
+ if (t.t_ms === "never") {
+ return "never";
+ }
+ return new Date(t.t_ms).toISOString();
+ }
+ AbsoluteTime.stringify = stringify;
+})(AbsoluteTime || (AbsoluteTime = {}));
+const SECONDS = 1000;
+const MINUTES = SECONDS * 60;
+const HOURS = MINUTES * 60;
+const DAYS = HOURS * 24;
+const MONTHS = DAYS * 30;
+const YEARS = DAYS * 365;
+function durationFromSpec(spec) {
+ var _a, _b, _c, _d, _e, _f;
+ let d_ms = 0;
+ d_ms += ((_a = spec.seconds) !== null && _a !== void 0 ? _a : 0) * SECONDS;
+ d_ms += ((_b = spec.minutes) !== null && _b !== void 0 ? _b : 0) * MINUTES;
+ d_ms += ((_c = spec.hours) !== null && _c !== void 0 ? _c : 0) * HOURS;
+ d_ms += ((_d = spec.days) !== null && _d !== void 0 ? _d : 0) * DAYS;
+ d_ms += ((_e = spec.months) !== null && _e !== void 0 ? _e : 0) * MONTHS;
+ d_ms += ((_f = spec.years) !== null && _f !== void 0 ? _f : 0) * YEARS;
+ return { d_ms };
+}
+function durationMin(d1, d2) {
+ if (d1.d_ms === "forever") {
+ return { d_ms: d2.d_ms };
+ }
+ if (d2.d_ms === "forever") {
+ return { d_ms: d1.d_ms };
+ }
+ return { d_ms: Math.min(d1.d_ms, d2.d_ms) };
+}
+function durationMax(d1, d2) {
+ if (d1.d_ms === "forever") {
+ return { d_ms: "forever" };
+ }
+ if (d2.d_ms === "forever") {
+ return { d_ms: "forever" };
+ }
+ return { d_ms: Math.max(d1.d_ms, d2.d_ms) };
+}
+function durationMul(d, n) {
+ if (d.d_ms === "forever") {
+ return { d_ms: "forever" };
+ }
+ return { d_ms: Math.round(d.d_ms * n) };
+}
+const codecForTimestamp = {
+ decode(x, c) {
+ // Compatibility, should be removed soon.
+ const t_ms = x.t_ms;
+ if (typeof t_ms === "string") {
+ if (t_ms === "never") {
+ return { t_s: "never" };
+ }
+ }
+ else if (typeof t_ms === "number") {
+ return { t_s: Math.floor(t_ms / 1000) };
+ }
+ const t_s = x.t_s;
+ if (typeof t_s === "string") {
+ if (t_s === "never") {
+ return { t_s: "never" };
+ }
+ throw Error(`expected timestamp at ${renderContext(c)}`);
+ }
+ if (typeof t_s === "number") {
+ return { t_s };
+ }
+ throw Error(`expected timestamp at ${renderContext(c)}`);
+ },
+};
+const codecForDuration = {
+ decode(x, c) {
+ const d_us = x.d_us;
+ if (typeof d_us === "string") {
+ if (d_us === "forever") {
+ return { d_us: "forever" };
+ }
+ throw Error(`expected duration at ${renderContext(c)}`);
+ }
+ if (typeof d_us === "number") {
+ return { d_us };
+ }
+ throw Error(`expected duration at ${renderContext(c)}`);
+ },
+};
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var DenomKeyType;
+(function (DenomKeyType) {
+ DenomKeyType["Rsa"] = "RSA";
+ DenomKeyType["ClauseSchnorr"] = "CS";
+})(DenomKeyType || (DenomKeyType = {}));
+(function (DenomKeyType) {
+ function toIntTag(t) {
+ switch (t) {
+ case DenomKeyType.Rsa:
+ return 1;
+ case DenomKeyType.ClauseSchnorr:
+ return 2;
+ }
+ }
+ DenomKeyType.toIntTag = toIntTag;
+})(DenomKeyType || (DenomKeyType = {}));
+const codecForRsaBlindedDenominationSignature = () => buildCodecForObject()
+ .property("cipher", codecForConstString(DenomKeyType.Rsa))
+ .property("blinded_rsa_signature", codecForString())
+ .build("RsaBlindedDenominationSignature");
+const codecForBlindedDenominationSignature = () => buildCodecForUnion()
+ .discriminateOn("cipher")
+ .alternative(DenomKeyType.Rsa, codecForRsaBlindedDenominationSignature())
+ .build("BlindedDenominationSignature");
+var DenominationPubKey;
+(function (DenominationPubKey) {
+ function cmp(p1, p2) {
+ var _a, _b, _c, _d, _e, _f, _g, _h;
+ if (p1.cipher < p2.cipher) {
+ return -1;
+ }
+ else if (p1.cipher > p2.cipher) {
+ return +1;
+ }
+ else if (p1.cipher === DenomKeyType.Rsa &&
+ p2.cipher === DenomKeyType.Rsa) {
+ if (((_a = p1.age_mask) !== null && _a !== void 0 ? _a : 0) < ((_b = p2.age_mask) !== null && _b !== void 0 ? _b : 0)) {
+ return -1;
+ }
+ else if (((_c = p1.age_mask) !== null && _c !== void 0 ? _c : 0) > ((_d = p2.age_mask) !== null && _d !== void 0 ? _d : 0)) {
+ return 1;
+ }
+ return strcmp(p1.rsa_public_key, p2.rsa_public_key);
+ }
+ else if (p1.cipher === DenomKeyType.ClauseSchnorr &&
+ p2.cipher === DenomKeyType.ClauseSchnorr) {
+ if (((_e = p1.age_mask) !== null && _e !== void 0 ? _e : 0) < ((_f = p2.age_mask) !== null && _f !== void 0 ? _f : 0)) {
+ return -1;
+ }
+ else if (((_g = p1.age_mask) !== null && _g !== void 0 ? _g : 0) > ((_h = p2.age_mask) !== null && _h !== void 0 ? _h : 0)) {
+ return 1;
+ }
+ return strcmp(p1.cs_public_key, p2.cs_public_key);
+ }
+ else {
+ throw Error("unsupported cipher");
+ }
+ }
+ DenominationPubKey.cmp = cmp;
+})(DenominationPubKey || (DenominationPubKey = {}));
+const codecForRsaDenominationPubKey = () => buildCodecForObject()
+ .property("cipher", codecForConstString(DenomKeyType.Rsa))
+ .property("rsa_public_key", codecForString())
+ .property("age_mask", codecForNumber())
+ .build("DenominationPubKey");
+const codecForCsDenominationPubKey = () => buildCodecForObject()
+ .property("cipher", codecForConstString(DenomKeyType.ClauseSchnorr))
+ .property("cs_public_key", codecForString())
+ .property("age_mask", codecForNumber())
+ .build("CsDenominationPubKey");
+const codecForDenominationPubKey = () => buildCodecForUnion()
+ .discriminateOn("cipher")
+ .alternative(DenomKeyType.Rsa, codecForRsaDenominationPubKey())
+ .alternative(DenomKeyType.ClauseSchnorr, codecForCsDenominationPubKey())
+ .build("DenominationPubKey");
+const codecForBankWithdrawalOperationPostResponse = () => buildCodecForObject()
+ .property("transfer_done", codecForBoolean())
+ .build("BankWithdrawalOperationPostResponse");
+const codecForDenomination = () => buildCodecForObject()
+ .property("value", codecForString())
+ .property("denom_pub", codecForDenominationPubKey())
+ .property("fee_withdraw", codecForString())
+ .property("fee_deposit", codecForString())
+ .property("fee_refresh", codecForString())
+ .property("fee_refund", codecForString())
+ .property("stamp_start", codecForTimestamp)
+ .property("stamp_expire_withdraw", codecForTimestamp)
+ .property("stamp_expire_legal", codecForTimestamp)
+ .property("stamp_expire_deposit", codecForTimestamp)
+ .property("master_sig", codecForString())
+ .build("Denomination");
+const codecForAuditorDenomSig = () => buildCodecForObject()
+ .property("denom_pub_h", codecForString())
+ .property("auditor_sig", codecForString())
+ .build("AuditorDenomSig");
+const codecForAuditor = () => buildCodecForObject()
+ .property("auditor_pub", codecForString())
+ .property("auditor_url", codecForString())
+ .property("denomination_keys", codecForList(codecForAuditorDenomSig()))
+ .build("Auditor");
+const codecForExchangeHandle = () => buildCodecForObject()
+ .property("master_pub", codecForString())
+ .property("url", codecForString())
+ .build("ExchangeHandle");
+const codecForAuditorHandle = () => buildCodecForObject()
+ .property("name", codecForString())
+ .property("auditor_pub", codecForString())
+ .property("url", codecForString())
+ .build("AuditorHandle");
+const codecForLocation = () => buildCodecForObject()
+ .property("country", codecOptional(codecForString()))
+ .property("country_subdivision", codecOptional(codecForString()))
+ .property("building_name", codecOptional(codecForString()))
+ .property("building_number", codecOptional(codecForString()))
+ .property("district", codecOptional(codecForString()))
+ .property("street", codecOptional(codecForString()))
+ .property("post_code", codecOptional(codecForString()))
+ .property("town", codecOptional(codecForString()))
+ .property("town_location", codecOptional(codecForString()))
+ .property("address_lines", codecOptional(codecForList(codecForString())))
+ .build("Location");
+const codecForMerchantInfo = () => buildCodecForObject()
+ .property("name", codecForString())
+ .property("address", codecOptional(codecForLocation()))
+ .property("jurisdiction", codecOptional(codecForLocation()))
+ .build("MerchantInfo");
+const codecForInternationalizedString = () => codecForMap(codecForString());
+const codecForProduct = () => buildCodecForObject()
+ .property("product_id", codecOptional(codecForString()))
+ .property("description", codecForString())
+ .property("description_i18n", codecOptional(codecForInternationalizedString()))
+ .property("quantity", codecOptional(codecForNumber()))
+ .property("unit", codecOptional(codecForString()))
+ .property("price", codecOptional(codecForString()))
+ .build("Tax");
+const codecForContractTerms = () => buildCodecForObject()
+ .property("order_id", codecForString())
+ .property("fulfillment_url", codecOptional(codecForString()))
+ .property("fulfillment_message", codecOptional(codecForString()))
+ .property("fulfillment_message_i18n", codecOptional(codecForInternationalizedString()))
+ .property("merchant_base_url", codecForString())
+ .property("h_wire", codecForString())
+ .property("auto_refund", codecOptional(codecForDuration))
+ .property("wire_method", codecForString())
+ .property("summary", codecForString())
+ .property("summary_i18n", codecOptional(codecForInternationalizedString()))
+ .property("nonce", codecForString())
+ .property("amount", codecForString())
+ .property("auditors", codecForList(codecForAuditorHandle()))
+ .property("pay_deadline", codecForTimestamp)
+ .property("refund_deadline", codecForTimestamp)
+ .property("wire_transfer_deadline", codecForTimestamp)
+ .property("timestamp", codecForTimestamp)
+ .property("delivery_location", codecOptional(codecForLocation()))
+ .property("delivery_date", codecOptional(codecForTimestamp))
+ .property("max_fee", codecForString())
+ .property("max_wire_fee", codecOptional(codecForString()))
+ .property("merchant", codecForMerchantInfo())
+ .property("merchant_pub", codecForString())
+ .property("exchanges", codecForList(codecForExchangeHandle()))
+ .property("products", codecOptional(codecForList(codecForProduct())))
+ .property("extra", codecForAny())
+ .property("minimum_age", codecOptional(codecForNumber()))
+ .build("ContractTerms");
+const codecForBlindSigWrapperV2 = () => buildCodecForObject()
+ .property("blind_sig", codecForBlindedDenominationSignature())
+ .build("MerchantBlindSigWrapperV2");
+const codecForMerchantTipResponseV2 = () => buildCodecForObject()
+ .property("blind_sigs", codecForList(codecForBlindSigWrapperV2()))
+ .build("MerchantTipResponseV2");
+const codecForRecoup = () => buildCodecForObject()
+ .property("h_denom_pub", codecForString())
+ .build("Recoup");
+const codecForExchangeSigningKey = () => buildCodecForObject()
+ .property("key", codecForString())
+ .property("master_sig", codecForString())
+ .property("stamp_end", codecForTimestamp)
+ .property("stamp_start", codecForTimestamp)
+ .property("stamp_expire", codecForTimestamp)
+ .build("ExchangeSignKeyJson");
+const codecForGlobalFees = () => buildCodecForObject()
+ .property("start_date", codecForTimestamp)
+ .property("end_date", codecForTimestamp)
+ .property("history_fee", codecForAmountString())
+ .property("account_fee", codecForAmountString())
+ .property("purse_fee", codecForAmountString())
+ .property("history_expiration", codecForDuration)
+ .property("purse_account_limit", codecForNumber())
+ .property("purse_timeout", codecForDuration)
+ .property("master_sig", codecForString())
+ .build("GlobalFees");
+const codecForExchangeKeysJson = () => buildCodecForObject()
+ .property("denoms", codecForList(codecForDenomination()))
+ .property("master_public_key", codecForString())
+ .property("auditors", codecForList(codecForAuditor()))
+ .property("list_issue_date", codecForTimestamp)
+ .property("recoup", codecOptional(codecForList(codecForRecoup())))
+ .property("signkeys", codecForList(codecForExchangeSigningKey()))
+ .property("version", codecForString())
+ .property("reserve_closing_delay", codecForDuration)
+ .property("global_fees", codecForList(codecForGlobalFees()))
+ .build("ExchangeKeysJson");
+const codecForWireFeesJson = () => buildCodecForObject()
+ .property("wire_fee", codecForString())
+ .property("closing_fee", codecForString())
+ .property("sig", codecForString())
+ .property("start_date", codecForTimestamp)
+ .property("end_date", codecForTimestamp)
+ .build("WireFeesJson");
+const codecForAccountInfo = () => buildCodecForObject()
+ .property("payto_uri", codecForString())
+ .property("master_sig", codecForString())
+ .build("AccountInfo");
+const codecForExchangeWireJson = () => buildCodecForObject()
+ .property("accounts", codecForList(codecForAccountInfo()))
+ .property("fees", codecForMap(codecForList(codecForWireFeesJson())))
+ .build("ExchangeWireJson");
+const codecForProposal = () => buildCodecForObject()
+ .property("contract_terms", codecForAny())
+ .property("sig", codecForString())
+ .build("Proposal");
+const codecForCheckPaymentResponse = () => buildCodecForObject()
+ .property("order_status", codecForString())
+ .property("refunded", codecOptional(codecForBoolean()))
+ .property("refunded_amount", codecOptional(codecForString()))
+ .property("contract_terms", codecOptional(codecForAny()))
+ .property("taler_pay_uri", codecOptional(codecForString()))
+ .property("contract_url", codecOptional(codecForString()))
+ .build("CheckPaymentResponse");
+const codecForWithdrawOperationStatusResponse = () => buildCodecForObject()
+ .property("selection_done", codecForBoolean())
+ .property("transfer_done", codecForBoolean())
+ .property("aborted", codecForBoolean())
+ .property("amount", codecForString())
+ .property("sender_wire", codecOptional(codecForString()))
+ .property("suggested_exchange", codecOptional(codecForString()))
+ .property("confirm_transfer_url", codecOptional(codecForString()))
+ .property("wire_types", codecForList(codecForString()))
+ .build("WithdrawOperationStatusResponse");
+const codecForTipPickupGetResponse = () => buildCodecForObject()
+ .property("tip_amount", codecForString())
+ .property("exchange_url", codecForString())
+ .property("expiration", codecForTimestamp)
+ .build("TipPickupGetResponse");
+const codecForRecoupConfirmation = () => buildCodecForObject()
+ .property("reserve_pub", codecOptional(codecForString()))
+ .property("old_coin_pub", codecOptional(codecForString()))
+ .build("RecoupConfirmation");
+const codecForWithdrawResponse = () => buildCodecForObject()
+ .property("ev_sig", codecForBlindedDenominationSignature())
+ .build("WithdrawResponse");
+const codecForWithdrawBatchResponse = () => buildCodecForObject()
+ .property("ev_sigs", codecForList(codecForWithdrawResponse()))
+ .build("WithdrawBatchResponse");
+const codecForMerchantPayResponse = () => buildCodecForObject()
+ .property("sig", codecForString())
+ .build("MerchantPayResponse");
+const codecForExchangeMeltResponse = () => buildCodecForObject()
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("noreveal_index", codecForNumber())
+ .property("refresh_base_url", codecOptional(codecForString()))
+ .build("ExchangeMeltResponse");
+const codecForExchangeRevealItem = () => buildCodecForObject()
+ .property("ev_sig", codecForBlindedDenominationSignature())
+ .build("ExchangeRevealItem");
+const codecForExchangeRevealResponse = () => buildCodecForObject()
+ .property("ev_sigs", codecForList(codecForExchangeRevealItem()))
+ .build("ExchangeRevealResponse");
+const codecForMerchantCoinRefundSuccessStatus = () => buildCodecForObject()
+ .property("type", codecForConstString("success"))
+ .property("coin_pub", codecForString())
+ .property("exchange_status", codecForConstNumber(200))
+ .property("exchange_sig", codecForString())
+ .property("rtransaction_id", codecForNumber())
+ .property("refund_amount", codecForString())
+ .property("exchange_pub", codecForString())
+ .property("execution_time", codecForTimestamp)
+ .build("MerchantCoinRefundSuccessStatus");
+const codecForMerchantCoinRefundFailureStatus = () => buildCodecForObject()
+ .property("type", codecForConstString("failure"))
+ .property("coin_pub", codecForString())
+ .property("exchange_status", codecForNumber())
+ .property("rtransaction_id", codecForNumber())
+ .property("refund_amount", codecForString())
+ .property("exchange_code", codecOptional(codecForNumber()))
+ .property("exchange_reply", codecOptional(codecForAny()))
+ .property("execution_time", codecForTimestamp)
+ .build("MerchantCoinRefundFailureStatus");
+const codecForMerchantCoinRefundStatus = () => buildCodecForUnion()
+ .discriminateOn("type")
+ .alternative("success", codecForMerchantCoinRefundSuccessStatus())
+ .alternative("failure", codecForMerchantCoinRefundFailureStatus())
+ .build("MerchantCoinRefundStatus");
+const codecForMerchantOrderStatusPaid = () => buildCodecForObject()
+ .property("refund_amount", codecForString())
+ .property("refund_taken", codecForString())
+ .property("refund_pending", codecForBoolean())
+ .property("refunded", codecForBoolean())
+ .build("MerchantOrderStatusPaid");
+const codecForMerchantOrderRefundPickupResponse = () => buildCodecForObject()
+ .property("merchant_pub", codecForString())
+ .property("refund_amount", codecForString())
+ .property("refunds", codecForList(codecForMerchantCoinRefundStatus()))
+ .build("MerchantOrderRefundPickupResponse");
+const codecForMerchantAbortPayRefundSuccessStatus = () => buildCodecForObject()
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("exchange_status", codecForConstNumber(200))
+ .property("type", codecForConstString("success"))
+ .build("MerchantAbortPayRefundSuccessStatus");
+const codecForMerchantAbortPayRefundFailureStatus = () => buildCodecForObject()
+ .property("exchange_code", codecForNumber())
+ .property("exchange_reply", codecForAny())
+ .property("exchange_status", codecForNumber())
+ .property("type", codecForConstString("failure"))
+ .build("MerchantAbortPayRefundFailureStatus");
+const codecForMerchantAbortPayRefundStatus = () => buildCodecForUnion()
+ .discriminateOn("type")
+ .alternative("success", codecForMerchantAbortPayRefundSuccessStatus())
+ .alternative("failure", codecForMerchantAbortPayRefundFailureStatus())
+ .build("MerchantAbortPayRefundStatus");
+const codecForAbortResponse = () => buildCodecForObject()
+ .property("refunds", codecForList(codecForMerchantAbortPayRefundStatus()))
+ .build("AbortResponse");
+const codecForTalerConfigResponse = () => buildCodecForObject()
+ .property("name", codecForString())
+ .property("version", codecForString())
+ .property("currency", codecOptional(codecForString()))
+ .build("TalerConfigResponse");
+const codecForMerchantConfigResponse = () => buildCodecForObject()
+ .property("currency", codecForString())
+ .property("name", codecForString())
+ .property("version", codecForString())
+ .build("MerchantConfigResponse");
+var ExchangeProtocolVersion;
+(function (ExchangeProtocolVersion) {
+ /**
+ * Current version supported by the wallet.
+ */
+ ExchangeProtocolVersion[ExchangeProtocolVersion["V12"] = 12] = "V12";
+})(ExchangeProtocolVersion || (ExchangeProtocolVersion = {}));
+var MerchantProtocolVersion;
+(function (MerchantProtocolVersion) {
+ /**
+ * Current version supported by the wallet.
+ */
+ MerchantProtocolVersion[MerchantProtocolVersion["V3"] = 3] = "V3";
+})(MerchantProtocolVersion || (MerchantProtocolVersion = {}));
+const codecForDepositSuccess = () => buildCodecForObject()
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("exchange_timestamp", codecForTimestamp)
+ .property("transaction_base_url", codecOptional(codecForString()))
+ .build("DepositSuccess");
+const codecForExchangeGetContractResponse = () => buildCodecForObject()
+ .property("purse_pub", codecForString())
+ .property("econtract_sig", codecForString())
+ .property("econtract", codecForString())
+ .build("ExchangeGetContractResponse");
+
+/*
+ This file is part of TALER
+ (C) 2019 GNUnet e.V.
+
+ 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/>
+ */
+/**
+ * Check if we are running under nodejs.
+ */
+const isNode = typeof process !== "undefined" &&
+ typeof process.release !== "undefined" &&
+ process.release.name === "node";
+var LogLevel;
+(function (LogLevel) {
+ LogLevel["Trace"] = "trace";
+ LogLevel["Message"] = "message";
+ LogLevel["Info"] = "info";
+ LogLevel["Warn"] = "warn";
+ LogLevel["Error"] = "error";
+ LogLevel["None"] = "none";
+})(LogLevel || (LogLevel = {}));
+let globalLogLevel = LogLevel.Info;
+function writeNodeLog(message, tag, level, args) {
+ try {
+ let msg = `${new Date().toISOString()} ${tag} ${level} ${message}`;
+ if (args.length != 0) {
+ msg += ` ${JSON.stringify(args, undefined, 2)}\n`;
+ }
+ else {
+ msg += `\n`;
+ }
+ process.stderr.write(msg);
+ }
+ catch (e) {
+ // This can happen when we're trying to log something that doesn't want to be
+ // converted to a string.
+ let msg = `${new Date().toISOString()} (logger) FATAL `;
+ if (e instanceof Error) {
+ msg += `failed to write log: ${e.message}\n`;
+ }
+ else {
+ msg += "failed to write log\n";
+ }
+ process.stderr.write(msg);
+ }
+}
+/**
+ * Logger that writes to stderr when running under node,
+ * and uses the corresponding console.* method to log in the browser.
+ */
+class Logger {
+ constructor(tag) {
+ this.tag = tag;
+ }
+ shouldLogTrace() {
+ switch (globalLogLevel) {
+ case LogLevel.Trace:
+ return true;
+ case LogLevel.Message:
+ case LogLevel.Info:
+ case LogLevel.Warn:
+ case LogLevel.Error:
+ case LogLevel.None:
+ return false;
+ }
+ }
+ shouldLogInfo() {
+ switch (globalLogLevel) {
+ case LogLevel.Trace:
+ case LogLevel.Message:
+ case LogLevel.Info:
+ return true;
+ case LogLevel.Warn:
+ case LogLevel.Error:
+ case LogLevel.None:
+ return false;
+ }
+ }
+ shouldLogWarn() {
+ switch (globalLogLevel) {
+ case LogLevel.Trace:
+ case LogLevel.Message:
+ case LogLevel.Info:
+ case LogLevel.Warn:
+ return true;
+ case LogLevel.Error:
+ case LogLevel.None:
+ return false;
+ }
+ }
+ shouldLogError() {
+ switch (globalLogLevel) {
+ case LogLevel.Trace:
+ case LogLevel.Message:
+ case LogLevel.Info:
+ case LogLevel.Warn:
+ case LogLevel.Error:
+ return true;
+ case LogLevel.None:
+ return false;
+ }
+ }
+ info(message, ...args) {
+ if (!this.shouldLogInfo()) {
+ return;
+ }
+ if (isNode) {
+ writeNodeLog(message, this.tag, "INFO", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
+ }
+ }
+ warn(message, ...args) {
+ if (!this.shouldLogWarn()) {
+ return;
+ }
+ if (isNode) {
+ writeNodeLog(message, this.tag, "WARN", args);
+ }
+ else {
+ console.warn(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
+ }
+ }
+ error(message, ...args) {
+ if (!this.shouldLogError()) {
+ return;
+ }
+ if (isNode) {
+ writeNodeLog(message, this.tag, "ERROR", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} ERROR ` + message, ...args);
+ }
+ }
+ trace(message, ...args) {
+ if (!this.shouldLogTrace()) {
+ return;
+ }
+ if (isNode) {
+ writeNodeLog(message, this.tag, "TRACE", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} TRACE ` + message, ...args);
+ }
+ }
+ reportBreak() {
+ if (!this.shouldLogError()) {
+ return;
+ }
+ const location = new Error("programming error");
+ this.error(`assertion failed: ${location.stack}`);
+ }
+}
+
+var require$1 = module$1.createRequire('/');
+// DEFLATE is a complex format; to read this code, you should probably check the RFC first:
+// https://tools.ietf.org/html/rfc1951
+// You may also wish to take a look at the guide I made about this program:
+// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
+// Some of the following code is similar to that of UZIP.js:
+// https://github.com/photopea/UZIP.js
+// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.
+// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint
+// is better for memory in most engines (I *think*).
+// Mediocre shim
+var Worker;
+try {
+ Worker = require$1('worker_threads').Worker;
+}
+catch (e) {
+}
+
+// aliases for shorter compressed code (most minifers don't do this)
+var u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;
+// fixed length extra bits
+var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);
+// fixed distance extra bits
+// see fleb note
+var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);
+// code length index map
+var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
+// get base, reverse index map from extra bits
+var freb = function (eb, start) {
+ var b = new u16(31);
+ for (var i = 0; i < 31; ++i) {
+ b[i] = start += 1 << eb[i - 1];
+ }
+ // numbers here are at max 18 bits
+ var r = new u32(b[30]);
+ for (var i = 1; i < 30; ++i) {
+ for (var j = b[i]; j < b[i + 1]; ++j) {
+ r[j] = ((j - b[i]) << 5) | i;
+ }
+ }
+ return [b, r];
+};
+var _a$1 = freb(fleb, 2), fl = _a$1[0], revfl = _a$1[1];
+// we can ignore the fact that the other numbers are wrong; they never happen anyway
+fl[28] = 258, revfl[258] = 28;
+var _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];
+// map of value to reverse (assuming 16 bits)
+var rev = new u16(32768);
+for (var i = 0; i < 32768; ++i) {
+ // reverse table algorithm from SO
+ var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);
+ x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);
+ x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);
+ rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;
+}
+// create huffman tree from u8 "map": index -> code length for code index
+// mb (max bits) must be at most 15
+// TODO: optimize/split up?
+var hMap = (function (cd, mb, r) {
+ var s = cd.length;
+ // index
+ var i = 0;
+ // u16 "map": index -> # of codes with bit length = index
+ var l = new u16(mb);
+ // length of cd must be 288 (total # of codes)
+ for (; i < s; ++i) {
+ if (cd[i])
+ ++l[cd[i] - 1];
+ }
+ // u16 "map": index -> minimum code for bit length = index
+ var le = new u16(mb);
+ for (i = 0; i < mb; ++i) {
+ le[i] = (le[i - 1] + l[i - 1]) << 1;
+ }
+ var co;
+ if (r) {
+ // u16 "map": index -> number of actual bits, symbol for code
+ co = new u16(1 << mb);
+ // bits to remove for reverser
+ var rvb = 15 - mb;
+ for (i = 0; i < s; ++i) {
+ // ignore 0 lengths
+ if (cd[i]) {
+ // num encoding both symbol and bits read
+ var sv = (i << 4) | cd[i];
+ // free bits
+ var r_1 = mb - cd[i];
+ // start value
+ var v = le[cd[i] - 1]++ << r_1;
+ // m is end value
+ for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {
+ // every 16 bit value starting with the code yields the same result
+ co[rev[v] >>> rvb] = sv;
+ }
+ }
+ }
+ }
+ else {
+ co = new u16(s);
+ for (i = 0; i < s; ++i) {
+ if (cd[i]) {
+ co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);
+ }
+ }
+ }
+ return co;
+});
+// fixed length tree
+var flt = new u8(288);
+for (var i = 0; i < 144; ++i)
+ flt[i] = 8;
+for (var i = 144; i < 256; ++i)
+ flt[i] = 9;
+for (var i = 256; i < 280; ++i)
+ flt[i] = 7;
+for (var i = 280; i < 288; ++i)
+ flt[i] = 8;
+// fixed distance tree
+var fdt = new u8(32);
+for (var i = 0; i < 32; ++i)
+ fdt[i] = 5;
+// fixed length map
+var flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);
+// fixed distance map
+var fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);
+// find max of array
+var max = function (a) {
+ var m = a[0];
+ for (var i = 1; i < a.length; ++i) {
+ if (a[i] > m)
+ m = a[i];
+ }
+ return m;
+};
+// read d, starting at bit p and mask with m
+var bits = function (d, p, m) {
+ var o = (p / 8) | 0;
+ return ((d[o] | (d[o + 1] << 8)) >> (p & 7)) & m;
+};
+// read d, starting at bit p continuing for at least 16 bits
+var bits16 = function (d, p) {
+ var o = (p / 8) | 0;
+ return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >> (p & 7));
+};
+// get end of byte
+var shft = function (p) { return ((p + 7) / 8) | 0; };
+// typed array slice - allows garbage collector to free original reference,
+// while being more compatible than .slice
+var slc = function (v, s, e) {
+ if (s == null || s < 0)
+ s = 0;
+ if (e == null || e > v.length)
+ e = v.length;
+ // can't use .constructor in case user-supplied
+ var n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);
+ n.set(v.subarray(s, e));
+ return n;
+};
+// error codes
+var ec = [
+ 'unexpected EOF',
+ 'invalid block type',
+ 'invalid length/literal',
+ 'invalid distance',
+ 'stream finished',
+ 'no stream handler',
+ ,
+ 'no callback',
+ 'invalid UTF-8 data',
+ 'extra field too long',
+ 'date not in range 1980-2099',
+ 'filename too long',
+ 'stream finishing',
+ 'invalid zip data'
+ // determined by unknown compression method
+];
+var err = function (ind, msg, nt) {
+ var e = new Error(msg || ec[ind]);
+ e.code = ind;
+ if (Error.captureStackTrace)
+ Error.captureStackTrace(e, err);
+ if (!nt)
+ throw e;
+ return e;
+};
+// expands raw DEFLATE data
+var inflt = function (dat, buf, st) {
+ // source length
+ var sl = dat.length;
+ if (!sl || (st && st.f && !st.l))
+ return buf || new u8(0);
+ // have to estimate size
+ var noBuf = !buf || st;
+ // no state
+ var noSt = !st || st.i;
+ if (!st)
+ st = {};
+ // Assumes roughly 33% compression ratio average
+ if (!buf)
+ buf = new u8(sl * 3);
+ // ensure buffer can fit at least l elements
+ var cbuf = function (l) {
+ var bl = buf.length;
+ // need to increase size to fit
+ if (l > bl) {
+ // Double or set to necessary, whichever is greater
+ var nbuf = new u8(Math.max(bl * 2, l));
+ nbuf.set(buf);
+ buf = nbuf;
+ }
+ };
+ // last chunk bitpos bytes
+ var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
+ // total bits
+ var tbts = sl * 8;
+ do {
+ if (!lm) {
+ // BFINAL - this is only 1 when last chunk is next
+ final = bits(dat, pos, 1);
+ // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman
+ var type = bits(dat, pos + 1, 3);
+ pos += 3;
+ if (!type) {
+ // go to end of byte boundary
+ var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;
+ if (t > sl) {
+ if (noSt)
+ err(0);
+ break;
+ }
+ // ensure size
+ if (noBuf)
+ cbuf(bt + l);
+ // Copy over uncompressed data
+ buf.set(dat.subarray(s, t), bt);
+ // Get new bitpos, update byte count
+ st.b = bt += l, st.p = pos = t * 8, st.f = final;
+ continue;
+ }
+ else if (type == 1)
+ lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
+ else if (type == 2) {
+ // literal lengths
+ var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
+ var tl = hLit + bits(dat, pos + 5, 31) + 1;
+ pos += 14;
+ // length+distance tree
+ var ldt = new u8(tl);
+ // code length tree
+ var clt = new u8(19);
+ for (var i = 0; i < hcLen; ++i) {
+ // use index map to get real code
+ clt[clim[i]] = bits(dat, pos + i * 3, 7);
+ }
+ pos += hcLen * 3;
+ // code lengths bits
+ var clb = max(clt), clbmsk = (1 << clb) - 1;
+ // code lengths map
+ var clm = hMap(clt, clb, 1);
+ for (var i = 0; i < tl;) {
+ var r = clm[bits(dat, pos, clbmsk)];
+ // bits read
+ pos += r & 15;
+ // symbol
+ var s = r >>> 4;
+ // code length to copy
+ if (s < 16) {
+ ldt[i++] = s;
+ }
+ else {
+ // copy count
+ var c = 0, n = 0;
+ if (s == 16)
+ n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
+ else if (s == 17)
+ n = 3 + bits(dat, pos, 7), pos += 3;
+ else if (s == 18)
+ n = 11 + bits(dat, pos, 127), pos += 7;
+ while (n--)
+ ldt[i++] = c;
+ }
+ }
+ // length tree distance tree
+ var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
+ // max length bits
+ lbt = max(lt);
+ // max dist bits
+ dbt = max(dt);
+ lm = hMap(lt, lbt, 1);
+ dm = hMap(dt, dbt, 1);
+ }
+ else
+ err(1);
+ if (pos > tbts) {
+ if (noSt)
+ err(0);
+ break;
+ }
+ }
+ // Make sure the buffer can hold this + the largest possible addition
+ // Maximum chunk size (practically, theoretically infinite) is 2^17;
+ if (noBuf)
+ cbuf(bt + 131072);
+ var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
+ var lpos = pos;
+ for (;; lpos = pos) {
+ // bits read, code
+ var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
+ pos += c & 15;
+ if (pos > tbts) {
+ if (noSt)
+ err(0);
+ break;
+ }
+ if (!c)
+ err(2);
+ if (sym < 256)
+ buf[bt++] = sym;
+ else if (sym == 256) {
+ lpos = pos, lm = null;
+ break;
+ }
+ else {
+ var add = sym - 254;
+ // no extra bits needed if less
+ if (sym > 264) {
+ // index
+ var i = sym - 257, b = fleb[i];
+ add = bits(dat, pos, (1 << b) - 1) + fl[i];
+ pos += b;
+ }
+ // dist
+ var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
+ if (!d)
+ err(3);
+ pos += d & 15;
+ var dt = fd[dsym];
+ if (dsym > 3) {
+ var b = fdeb[dsym];
+ dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;
+ }
+ if (pos > tbts) {
+ if (noSt)
+ err(0);
+ break;
+ }
+ if (noBuf)
+ cbuf(bt + 131072);
+ var end = bt + add;
+ for (; bt < end; bt += 4) {
+ buf[bt] = buf[bt - dt];
+ buf[bt + 1] = buf[bt + 1 - dt];
+ buf[bt + 2] = buf[bt + 2 - dt];
+ buf[bt + 3] = buf[bt + 3 - dt];
+ }
+ bt = end;
+ }
+ }
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
+ if (lm)
+ final = 1, st.m = lbt, st.d = dm, st.n = dbt;
+ } while (!final);
+ return bt == buf.length ? buf : slc(buf, 0, bt);
+};
+// starting at p, write the minimum number of bits that can hold v to d
+var wbits = function (d, p, v) {
+ v <<= p & 7;
+ var o = (p / 8) | 0;
+ d[o] |= v;
+ d[o + 1] |= v >>> 8;
+};
+// starting at p, write the minimum number of bits (>8) that can hold v to d
+var wbits16 = function (d, p, v) {
+ v <<= p & 7;
+ var o = (p / 8) | 0;
+ d[o] |= v;
+ d[o + 1] |= v >>> 8;
+ d[o + 2] |= v >>> 16;
+};
+// creates code lengths from a frequency table
+var hTree = function (d, mb) {
+ // Need extra info to make a tree
+ var t = [];
+ for (var i = 0; i < d.length; ++i) {
+ if (d[i])
+ t.push({ s: i, f: d[i] });
+ }
+ var s = t.length;
+ var t2 = t.slice();
+ if (!s)
+ return [et, 0];
+ if (s == 1) {
+ var v = new u8(t[0].s + 1);
+ v[t[0].s] = 1;
+ return [v, 1];
+ }
+ t.sort(function (a, b) { return a.f - b.f; });
+ // after i2 reaches last ind, will be stopped
+ // freq must be greater than largest possible number of symbols
+ t.push({ s: -1, f: 25001 });
+ var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;
+ t[0] = { s: -1, f: l.f + r.f, l: l, r: r };
+ // efficient algorithm from UZIP.js
+ // i0 is lookbehind, i2 is lookahead - after processing two low-freq
+ // symbols that combined have high freq, will start processing i2 (high-freq,
+ // non-composite) symbols instead
+ // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/
+ while (i1 != s - 1) {
+ l = t[t[i0].f < t[i2].f ? i0++ : i2++];
+ r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
+ t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };
+ }
+ var maxSym = t2[0].s;
+ for (var i = 1; i < s; ++i) {
+ if (t2[i].s > maxSym)
+ maxSym = t2[i].s;
+ }
+ // code lengths
+ var tr = new u16(maxSym + 1);
+ // max bits in tree
+ var mbt = ln(t[i1 - 1], tr, 0);
+ if (mbt > mb) {
+ // more algorithms from UZIP.js
+ // TODO: find out how this code works (debt)
+ // ind debt
+ var i = 0, dt = 0;
+ // left cost
+ var lft = mbt - mb, cst = 1 << lft;
+ t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });
+ for (; i < s; ++i) {
+ var i2_1 = t2[i].s;
+ if (tr[i2_1] > mb) {
+ dt += cst - (1 << (mbt - tr[i2_1]));
+ tr[i2_1] = mb;
+ }
+ else
+ break;
+ }
+ dt >>>= lft;
+ while (dt > 0) {
+ var i2_2 = t2[i].s;
+ if (tr[i2_2] < mb)
+ dt -= 1 << (mb - tr[i2_2]++ - 1);
+ else
+ ++i;
+ }
+ for (; i >= 0 && dt; --i) {
+ var i2_3 = t2[i].s;
+ if (tr[i2_3] == mb) {
+ --tr[i2_3];
+ ++dt;
+ }
+ }
+ mbt = mb;
+ }
+ return [new u8(tr), mbt];
+};
+// get the max length and assign length codes
+var ln = function (n, l, d) {
+ return n.s == -1
+ ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))
+ : (l[n.s] = d);
+};
+// length codes generation
+var lc = function (c) {
+ var s = c.length;
+ // Note that the semicolon was intentional
+ while (s && !c[--s])
+ ;
+ var cl = new u16(++s);
+ // ind num streak
+ var cli = 0, cln = c[0], cls = 1;
+ var w = function (v) { cl[cli++] = v; };
+ for (var i = 1; i <= s; ++i) {
+ if (c[i] == cln && i != s)
+ ++cls;
+ else {
+ if (!cln && cls > 2) {
+ for (; cls > 138; cls -= 138)
+ w(32754);
+ if (cls > 2) {
+ w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);
+ cls = 0;
+ }
+ }
+ else if (cls > 3) {
+ w(cln), --cls;
+ for (; cls > 6; cls -= 6)
+ w(8304);
+ if (cls > 2)
+ w(((cls - 3) << 5) | 8208), cls = 0;
+ }
+ while (cls--)
+ w(cln);
+ cls = 1;
+ cln = c[i];
+ }
+ }
+ return [cl.subarray(0, cli), s];
+};
+// calculate the length of output from tree, code lengths
+var clen = function (cf, cl) {
+ var l = 0;
+ for (var i = 0; i < cl.length; ++i)
+ l += cf[i] * cl[i];
+ return l;
+};
+// writes a fixed block
+// returns the new bit pos
+var wfblk = function (out, pos, dat) {
+ // no need to write 00 as type: TypedArray defaults to 0
+ var s = dat.length;
+ var o = shft(pos + 2);
+ out[o] = s & 255;
+ out[o + 1] = s >>> 8;
+ out[o + 2] = out[o] ^ 255;
+ out[o + 3] = out[o + 1] ^ 255;
+ for (var i = 0; i < s; ++i)
+ out[o + i + 4] = dat[i];
+ return (o + 4 + s) * 8;
+};
+// writes a block
+var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
+ wbits(out, p++, final);
+ ++lf[256];
+ var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];
+ var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];
+ var _c = lc(dlt), lclt = _c[0], nlc = _c[1];
+ var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];
+ var lcfreq = new u16(19);
+ for (var i = 0; i < lclt.length; ++i)
+ lcfreq[lclt[i] & 31]++;
+ for (var i = 0; i < lcdt.length; ++i)
+ lcfreq[lcdt[i] & 31]++;
+ var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];
+ var nlcc = 19;
+ for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
+ ;
+ var flen = (bl + 5) << 3;
+ var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
+ var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
+ if (flen <= ftlen && flen <= dtlen)
+ return wfblk(out, p, dat.subarray(bs, bs + bl));
+ var lm, ll, dm, dl;
+ wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
+ if (dtlen < ftlen) {
+ lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
+ var llm = hMap(lct, mlcb, 0);
+ wbits(out, p, nlc - 257);
+ wbits(out, p + 5, ndc - 1);
+ wbits(out, p + 10, nlcc - 4);
+ p += 14;
+ for (var i = 0; i < nlcc; ++i)
+ wbits(out, p + 3 * i, lct[clim[i]]);
+ p += 3 * nlcc;
+ var lcts = [lclt, lcdt];
+ for (var it = 0; it < 2; ++it) {
+ var clct = lcts[it];
+ for (var i = 0; i < clct.length; ++i) {
+ var len = clct[i] & 31;
+ wbits(out, p, llm[len]), p += lct[len];
+ if (len > 15)
+ wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;
+ }
+ }
+ }
+ else {
+ lm = flm, ll = flt, dm = fdm, dl = fdt;
+ }
+ for (var i = 0; i < li; ++i) {
+ if (syms[i] > 255) {
+ var len = (syms[i] >>> 18) & 31;
+ wbits16(out, p, lm[len + 257]), p += ll[len + 257];
+ if (len > 7)
+ wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];
+ var dst = syms[i] & 31;
+ wbits16(out, p, dm[dst]), p += dl[dst];
+ if (dst > 3)
+ wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];
+ }
+ else {
+ wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];
+ }
+ }
+ wbits16(out, p, lm[256]);
+ return p + ll[256];
+};
+// deflate options (nice << 13) | chain
+var deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
+// empty
+var et = /*#__PURE__*/ new u8(0);
+// compresses data into a raw DEFLATE buffer
+var dflt = function (dat, lvl, plvl, pre, post, lst) {
+ var s = dat.length;
+ var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
+ // writing to this writes to the output buffer
+ var w = o.subarray(pre, o.length - post);
+ var pos = 0;
+ if (!lvl || s < 8) {
+ for (var i = 0; i <= s; i += 65535) {
+ // end
+ var e = i + 65535;
+ if (e >= s) {
+ // write final block
+ w[pos >> 3] = lst;
+ }
+ pos = wfblk(w, pos + 1, dat.subarray(i, e));
+ }
+ }
+ else {
+ var opt = deo[lvl - 1];
+ var n = opt >>> 13, c = opt & 8191;
+ var msk_1 = (1 << plvl) - 1;
+ // prev 2-byte val map curr 2-byte val map
+ var prev = new u16(32768), head = new u16(msk_1 + 1);
+ var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
+ var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };
+ // 24576 is an arbitrary number of maximum symbols per block
+ // 424 buffer for last block
+ var syms = new u32(25000);
+ // length/literal freq distance freq
+ var lf = new u16(288), df = new u16(32);
+ // l/lcnt exbits index l/lind waitdx bitpos
+ var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;
+ for (; i < s; ++i) {
+ // hash value
+ // deopt when i > s - 3 - at end, deopt acceptable
+ var hv = hsh(i);
+ // index mod 32768 previous index mod
+ var imod = i & 32767, pimod = head[hv];
+ prev[imod] = pimod;
+ head[hv] = imod;
+ // We always should modify head and prev, but only add symbols if
+ // this data is not yet processed ("wait" for wait index)
+ if (wi <= i) {
+ // bytes remaining
+ var rem = s - i;
+ if ((lc_1 > 7000 || li > 24576) && rem > 423) {
+ pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
+ li = lc_1 = eb = 0, bs = i;
+ for (var j = 0; j < 286; ++j)
+ lf[j] = 0;
+ for (var j = 0; j < 30; ++j)
+ df[j] = 0;
+ }
+ // len dist chain
+ var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;
+ if (rem > 2 && hv == hsh(i - dif)) {
+ var maxn = Math.min(n, rem) - 1;
+ var maxd = Math.min(32767, i);
+ // max possible length
+ // not capped at dif because decompressors implement "rolling" index population
+ var ml = Math.min(258, rem);
+ while (dif <= maxd && --ch_1 && imod != pimod) {
+ if (dat[i + l] == dat[i + l - dif]) {
+ var nl = 0;
+ for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)
+ ;
+ if (nl > l) {
+ l = nl, d = dif;
+ // break out early when we reach "nice" (we are satisfied enough)
+ if (nl > maxn)
+ break;
+ // now, find the rarest 2-byte sequence within this
+ // length of literals and search for that instead.
+ // Much faster than just using the start
+ var mmd = Math.min(dif, nl - 2);
+ var md = 0;
+ for (var j = 0; j < mmd; ++j) {
+ var ti = (i - dif + j + 32768) & 32767;
+ var pti = prev[ti];
+ var cd = (ti - pti + 32768) & 32767;
+ if (cd > md)
+ md = cd, pimod = ti;
+ }
+ }
+ }
+ // check the previous match
+ imod = pimod, pimod = prev[imod];
+ dif += (imod - pimod + 32768) & 32767;
+ }
+ }
+ // d will be nonzero only when a match was found
+ if (d) {
+ // store both dist and len data in one Uint32
+ // Make sure this is recognized as a len/dist with 28th bit (2^28)
+ syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];
+ var lin = revfl[l] & 31, din = revfd[d] & 31;
+ eb += fleb[lin] + fdeb[din];
+ ++lf[257 + lin];
+ ++df[din];
+ wi = i + l;
+ ++lc_1;
+ }
+ else {
+ syms[li++] = dat[i];
+ ++lf[dat[i]];
+ }
+ }
+ }
+ pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
+ // this is the easiest way to avoid needing to maintain state
+ if (!lst && pos & 7)
+ pos = wfblk(w, pos + 1, et);
+ }
+ return slc(o, 0, pre + shft(pos) + post);
+};
+// CRC32 table
+var crct = /*#__PURE__*/ (function () {
+ var t = new Int32Array(256);
+ for (var i = 0; i < 256; ++i) {
+ var c = i, k = 9;
+ while (--k)
+ c = ((c & 1) && -306674912) ^ (c >>> 1);
+ t[i] = c;
+ }
+ return t;
+})();
+// CRC32
+var crc = function () {
+ var c = -1;
+ return {
+ p: function (d) {
+ // closures have awful performance
+ var cr = c;
+ for (var i = 0; i < d.length; ++i)
+ cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);
+ c = cr;
+ },
+ d: function () { return ~c; }
+ };
+};
+// Alder32
+var adler = function () {
+ var a = 1, b = 0;
+ return {
+ p: function (d) {
+ // closures have awful performance
+ var n = a, m = b;
+ var l = d.length | 0;
+ for (var i = 0; i != l;) {
+ var e = Math.min(i + 2655, l);
+ for (; i < e; ++i)
+ m += n += d[i];
+ n = (n & 65535) + 15 * (n >> 16), m = (m & 65535) + 15 * (m >> 16);
+ }
+ a = n, b = m;
+ },
+ d: function () {
+ a %= 65521, b %= 65521;
+ return (a & 255) << 24 | (a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8);
+ }
+ };
+};
+// deflate with opts
+var dopt = function (dat, opt, pre, post, st) {
+ return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);
+};
+// write bytes
+var wbytes = function (d, b, v) {
+ for (; v; ++b)
+ d[b] = v, v >>>= 8;
+};
+// gzip header
+var gzh = function (c, o) {
+ var fn = o.filename;
+ c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix
+ if (o.mtime != 0)
+ wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));
+ if (fn) {
+ c[3] = 8;
+ for (var i = 0; i <= fn.length; ++i)
+ c[i + 10] = fn.charCodeAt(i);
+ }
+};
+// gzip footer: -8 to -4 = CRC, -4 to -0 is length
+// gzip start
+var gzs = function (d) {
+ if (d[0] != 31 || d[1] != 139 || d[2] != 8)
+ err(6, 'invalid gzip data');
+ var flg = d[3];
+ var st = 10;
+ if (flg & 4)
+ st += d[10] | (d[11] << 8) + 2;
+ for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
+ ;
+ return st + (flg & 2);
+};
+// gzip length
+var gzl = function (d) {
+ var l = d.length;
+ return ((d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) | (d[l - 1] << 24)) >>> 0;
+};
+// gzip header length
+var gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };
+// zlib header
+var zlh = function (c, o) {
+ var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;
+ c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1);
+};
+// zlib valid
+var zlv = function (d) {
+ if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))
+ err(6, 'invalid zlib data');
+ if (d[1] & 32)
+ err(6, 'invalid zlib data: preset dictionaries not supported');
+};
+/**
+ * Compresses data with GZIP
+ * @param data The data to compress
+ * @param opts The compression options
+ * @returns The gzipped version of the data
+ */
+function gzipSync(data, opts) {
+ if (!opts)
+ opts = {};
+ var c = crc(), l = data.length;
+ c.p(data);
+ var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
+ return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
+}
+/**
+ * Expands GZIP data
+ * @param data The data to decompress
+ * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.
+ * @returns The decompressed version of the data
+ */
+function gunzipSync(data, out) {
+ return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));
+}
+/**
+ * Compress data with Zlib
+ * @param data The data to compress
+ * @param opts The compression options
+ * @returns The zlib-compressed version of the data
+ */
+function zlibSync(data, opts) {
+ if (!opts)
+ opts = {};
+ var a = adler();
+ a.p(data);
+ var d = dopt(data, opts, 2, 4);
+ return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;
+}
+/**
+ * Expands Zlib data
+ * @param data The data to decompress
+ * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
+ * @returns The decompressed version of the data
+ */
+function unzlibSync(data, out) {
+ return inflt((zlv(data), data.subarray(2, -4)), out);
+}
+// text decoder
+var td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();
+// text decoder stream
+var tds = 0;
+try {
+ td.decode(et, { stream: true });
+ tds = 1;
+}
+catch (e) { }
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+function getRandomBytes(n) {
+ return randomBytes(n);
+}
+function getRandomBytesF(n) {
+ return randomBytes(n);
+}
+const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
+class EncodingError extends Error {
+ constructor() {
+ super("Encoding error");
+ Object.setPrototypeOf(this, EncodingError.prototype);
+ }
+}
+function getValue(chr) {
+ let a = chr;
+ switch (chr) {
+ case "O":
+ case "o":
+ a = "0;";
+ break;
+ case "i":
+ case "I":
+ case "l":
+ case "L":
+ a = "1";
+ break;
+ case "u":
+ case "U":
+ a = "V";
+ }
+ if (a >= "0" && a <= "9") {
+ return a.charCodeAt(0) - "0".charCodeAt(0);
+ }
+ if (a >= "a" && a <= "z")
+ a = a.toUpperCase();
+ let dec = 0;
+ if (a >= "A" && a <= "Z") {
+ if ("I" < a)
+ dec++;
+ if ("L" < a)
+ dec++;
+ if ("O" < a)
+ dec++;
+ if ("U" < a)
+ dec++;
+ return a.charCodeAt(0) - "A".charCodeAt(0) + 10 - dec;
+ }
+ throw new EncodingError();
+}
+function encodeCrock(data) {
+ const dataBytes = new Uint8Array(data);
+ let sb = "";
+ const size = data.byteLength;
+ let bitBuf = 0;
+ let numBits = 0;
+ let pos = 0;
+ while (pos < size || numBits > 0) {
+ if (pos < size && numBits < 5) {
+ const d = dataBytes[pos++];
+ bitBuf = (bitBuf << 8) | d;
+ numBits += 8;
+ }
+ if (numBits < 5) {
+ // zero-padding
+ bitBuf = bitBuf << (5 - numBits);
+ numBits = 5;
+ }
+ const v = (bitBuf >>> (numBits - 5)) & 31;
+ sb += encTable[v];
+ numBits -= 5;
+ }
+ return sb;
+}
+function decodeCrock(encoded) {
+ const size = encoded.length;
+ let bitpos = 0;
+ let bitbuf = 0;
+ let readPosition = 0;
+ const outLen = Math.floor((size * 5) / 8);
+ const out = new Uint8Array(outLen);
+ let outPos = 0;
+ while (readPosition < size || bitpos > 0) {
+ if (readPosition < size) {
+ const v = getValue(encoded[readPosition++]);
+ bitbuf = (bitbuf << 5) | v;
+ bitpos += 5;
+ }
+ while (bitpos >= 8) {
+ const d = (bitbuf >>> (bitpos - 8)) & 0xff;
+ out[outPos++] = d;
+ bitpos -= 8;
+ }
+ if (readPosition == size && bitpos > 0) {
+ bitbuf = (bitbuf << (8 - bitpos)) & 0xff;
+ bitpos = bitbuf == 0 ? 0 : 8;
+ }
+ }
+ return out;
+}
+function eddsaGetPublic(eddsaPriv) {
+ const pair = crypto_sign_keyPair_fromSeed(eddsaPriv);
+ return pair.publicKey;
+}
+function ecdheGetPublic(ecdhePriv) {
+ return scalarMult_base(ecdhePriv);
+}
+function keyExchangeEcdheEddsa(ecdhePriv, eddsaPub) {
+ const curve25519Pub = sign_ed25519_pk_to_curve25519(eddsaPub);
+ const x = scalarMult(ecdhePriv, curve25519Pub);
+ return hash$1(x);
+}
+/**
+ * KDF modulo a big integer.
+ */
+function kdfMod(n, ikm, salt, info) {
+ const nbits = n.bitLength().toJSNumber();
+ const buflen = Math.floor((nbits - 1) / 8 + 1);
+ const mask = (1 << (8 - (buflen * 8 - nbits))) - 1;
+ let counter = 0;
+ while (true) {
+ const ctx = new Uint8Array(info.byteLength + 2);
+ ctx.set(info, 0);
+ ctx[ctx.length - 2] = (counter >>> 8) & 0xff;
+ ctx[ctx.length - 1] = counter & 0xff;
+ const buf = kdf(buflen, ikm, salt, ctx);
+ const arr = Array.from(buf);
+ arr[0] = arr[0] & mask;
+ const r = bigint.fromArray(arr, 256, false);
+ if (r.lt(n)) {
+ return r;
+ }
+ counter++;
+ }
+}
+// Newer versions of node have TextEncoder and TextDecoder as a global,
+// just like modern browsers.
+// In older versions of node or environments that do not have these
+// globals, they must be polyfilled (by adding them to globa/globalThis)
+// before stringToBytes or bytesToString is called the first time.
+let encoder;
+let decoder;
+function stringToBytes(s) {
+ if (!encoder) {
+ // @ts-ignore
+ encoder = new TextEncoder();
+ }
+ return encoder.encode(s);
+}
+function bytesToString(b) {
+ if (!decoder) {
+ // @ts-ignore
+ decoder = new TextDecoder();
+ }
+ return decoder.decode(b);
+}
+function loadBigInt(arr) {
+ return bigint.fromArray(Array.from(arr), 256, false);
+}
+function rsaBlindingKeyDerive(rsaPub, bks) {
+ const salt = stringToBytes("Blinding KDF extractor HMAC key");
+ const info = stringToBytes("Blinding KDF");
+ return kdfMod(rsaPub.N, bks, salt, info);
+}
+/*
+ * Test for malicious RSA key.
+ *
+ * Assuming n is an RSA modulous and r is generated using a call to
+ * GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a
+ * malicious RSA key designed to deanomize the user.
+ *
+ * @param r KDF result
+ * @param n RSA modulus of the public key
+ */
+function rsaGcdValidate(r, n) {
+ const t = bigint.gcd(r, n);
+ if (!t.equals(bigint.one)) {
+ throw Error("malicious RSA public key");
+ }
+}
+function rsaFullDomainHash(hm, rsaPub) {
+ const info = stringToBytes("RSA-FDA FTpsW!");
+ const salt = rsaPubEncode(rsaPub);
+ const r = kdfMod(rsaPub.N, hm, salt, info);
+ rsaGcdValidate(r, rsaPub.N);
+ return r;
+}
+function rsaPubDecode(rsaPub) {
+ const modulusLength = (rsaPub[0] << 8) | rsaPub[1];
+ const exponentLength = (rsaPub[2] << 8) | rsaPub[3];
+ if (4 + exponentLength + modulusLength != rsaPub.length) {
+ throw Error("invalid RSA public key (format wrong)");
+ }
+ const modulus = rsaPub.slice(4, 4 + modulusLength);
+ const exponent = rsaPub.slice(4 + modulusLength, 4 + modulusLength + exponentLength);
+ const res = {
+ N: loadBigInt(modulus),
+ e: loadBigInt(exponent),
+ };
+ return res;
+}
+function rsaPubEncode(rsaPub) {
+ const mb = rsaPub.N.toArray(256).value;
+ const eb = rsaPub.e.toArray(256).value;
+ const out = new Uint8Array(4 + mb.length + eb.length);
+ out[0] = (mb.length >>> 8) & 0xff;
+ out[1] = mb.length & 0xff;
+ out[2] = (eb.length >>> 8) & 0xff;
+ out[3] = eb.length & 0xff;
+ out.set(mb, 4);
+ out.set(eb, 4 + mb.length);
+ return out;
+}
+function rsaBlind(hm, bks, rsaPubEnc) {
+ const rsaPub = rsaPubDecode(rsaPubEnc);
+ const data = rsaFullDomainHash(hm, rsaPub);
+ const r = rsaBlindingKeyDerive(rsaPub, bks);
+ const r_e = r.modPow(rsaPub.e, rsaPub.N);
+ const bm = r_e.multiply(data).mod(rsaPub.N);
+ return new Uint8Array(bm.toArray(256).value);
+}
+function rsaUnblind(sig, rsaPubEnc, bks) {
+ const rsaPub = rsaPubDecode(rsaPubEnc);
+ const blinded_s = loadBigInt(sig);
+ const r = rsaBlindingKeyDerive(rsaPub, bks);
+ const r_inv = r.modInv(rsaPub.N);
+ const s = blinded_s.multiply(r_inv).mod(rsaPub.N);
+ return new Uint8Array(s.toArray(256).value);
+}
+function rsaVerify(hm, rsaSig, rsaPubEnc) {
+ const rsaPub = rsaPubDecode(rsaPubEnc);
+ const d = rsaFullDomainHash(hm, rsaPub);
+ const sig = loadBigInt(rsaSig);
+ const sig_e = sig.modPow(rsaPub.e, rsaPub.N);
+ return sig_e.equals(d);
+}
+function typedArrayConcat(chunks) {
+ let payloadLen = 0;
+ for (const c of chunks) {
+ payloadLen += c.byteLength;
+ }
+ const buf = new ArrayBuffer(payloadLen);
+ const u8buf = new Uint8Array(buf);
+ let p = 0;
+ for (const c of chunks) {
+ u8buf.set(c, p);
+ p += c.byteLength;
+ }
+ return u8buf;
+}
+function hash(d) {
+ return hash$1(d);
+}
+/**
+ * Hash the input with SHA-512 and truncate the result
+ * to 32 bytes.
+ */
+function hashTruncate32(d) {
+ const sha512HashCode = hash$1(d);
+ return sha512HashCode.subarray(0, 32);
+}
+function hashCoinEv(coinEv, denomPubHash) {
+ const hashContext = createHashContext();
+ hashContext.update(decodeCrock(denomPubHash));
+ hashCoinEvInner(coinEv, hashContext);
+ return hashContext.finish();
+}
+new Logger("talerCrypto.ts");
+function hashCoinEvInner(coinEv, hashState) {
+ const hashInputBuf = new ArrayBuffer(4);
+ const uint8ArrayBuf = new Uint8Array(hashInputBuf);
+ const dv = new DataView(hashInputBuf);
+ dv.setUint32(0, DenomKeyType.toIntTag(coinEv.cipher));
+ hashState.update(uint8ArrayBuf);
+ switch (coinEv.cipher) {
+ case DenomKeyType.Rsa:
+ hashState.update(decodeCrock(coinEv.rsa_blinded_planchet));
+ return;
+ default:
+ throw new Error();
+ }
+}
+function hashCoinPub(coinPub, ach) {
+ if (!ach) {
+ return hash(decodeCrock(coinPub));
+ }
+ return hash(typedArrayConcat([decodeCrock(coinPub), decodeCrock(ach)]));
+}
+/**
+ * Hash a denomination public key.
+ */
+function hashDenomPub(pub) {
+ var _a, _b;
+ if (pub.cipher === DenomKeyType.Rsa) {
+ const pubBuf = decodeCrock(pub.rsa_public_key);
+ const hashInputBuf = new ArrayBuffer(pubBuf.length + 4 + 4);
+ const uint8ArrayBuf = new Uint8Array(hashInputBuf);
+ const dv = new DataView(hashInputBuf);
+ dv.setUint32(0, (_a = pub.age_mask) !== null && _a !== void 0 ? _a : 0);
+ dv.setUint32(4, DenomKeyType.toIntTag(pub.cipher));
+ uint8ArrayBuf.set(pubBuf, 8);
+ return hash$1(uint8ArrayBuf);
+ }
+ else if (pub.cipher === DenomKeyType.ClauseSchnorr) {
+ const pubBuf = decodeCrock(pub.cs_public_key);
+ const hashInputBuf = new ArrayBuffer(pubBuf.length + 4 + 4);
+ const uint8ArrayBuf = new Uint8Array(hashInputBuf);
+ const dv = new DataView(hashInputBuf);
+ dv.setUint32(0, (_b = pub.age_mask) !== null && _b !== void 0 ? _b : 0);
+ dv.setUint32(4, DenomKeyType.toIntTag(pub.cipher));
+ uint8ArrayBuf.set(pubBuf, 8);
+ return hash$1(uint8ArrayBuf);
+ }
+ else {
+ throw Error(`unsupported cipher (${pub.cipher}), unable to hash`);
+ }
+}
+function eddsaSign(msg, eddsaPriv) {
+ const pair = crypto_sign_keyPair_fromSeed(eddsaPriv);
+ return sign_detached(msg, pair.secretKey);
+}
+function eddsaVerify(msg, sig, eddsaPub) {
+ return sign_detached_verify(msg, sig, eddsaPub);
+}
+function createHashContext() {
+ return new HashState();
+}
+function bufferForUint32(n) {
+ const arrBuf = new ArrayBuffer(4);
+ const buf = new Uint8Array(arrBuf);
+ const dv = new DataView(arrBuf);
+ dv.setUint32(0, n);
+ return buf;
+}
+function setupTipPlanchet(secretSeed, denomPub, coinNumber) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const info = stringToBytes("taler-tip-coin-derivation");
+ const saltArrBuf = new ArrayBuffer(4);
+ const salt = new Uint8Array(saltArrBuf);
+ const saltDataView = new DataView(saltArrBuf);
+ saltDataView.setUint32(0, coinNumber);
+ const out = kdf(64, secretSeed, salt, info);
+ const coinPriv = out.slice(0, 32);
+ const bks = out.slice(32, 64);
+ let maybeAcp;
+ if (denomPub.age_mask != 0) {
+ maybeAcp = yield AgeRestriction.restrictionCommitSeeded(denomPub.age_mask, AgeRestriction.AGE_UNRESTRICTED, secretSeed);
+ }
+ return {
+ bks,
+ coinPriv,
+ coinPub: eddsaGetPublic(coinPriv),
+ maxAge: AgeRestriction.AGE_UNRESTRICTED,
+ ageCommitmentProof: maybeAcp,
+ };
+ });
+}
+/**
+ *
+ * @param paytoUri
+ * @param salt 16-byte salt
+ * @returns
+ */
+function hashWire(paytoUri, salt) {
+ const r = kdf(64, stringToBytes(paytoUri + "\0"), decodeCrock(salt), stringToBytes("merchant-wire-signature"));
+ return encodeCrock(r);
+}
+var TalerSignaturePurpose;
+(function (TalerSignaturePurpose) {
+ TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_TRACK_TRANSACTION"] = 1103] = "MERCHANT_TRACK_TRANSACTION";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_RESERVE_WITHDRAW"] = 1200] = "WALLET_RESERVE_WITHDRAW";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_DEPOSIT"] = 1201] = "WALLET_COIN_DEPOSIT";
+ TalerSignaturePurpose[TalerSignaturePurpose["GLOBAL_FEES"] = 1022] = "GLOBAL_FEES";
+ TalerSignaturePurpose[TalerSignaturePurpose["MASTER_DENOMINATION_KEY_VALIDITY"] = 1025] = "MASTER_DENOMINATION_KEY_VALIDITY";
+ TalerSignaturePurpose[TalerSignaturePurpose["MASTER_WIRE_FEES"] = 1028] = "MASTER_WIRE_FEES";
+ TalerSignaturePurpose[TalerSignaturePurpose["MASTER_WIRE_DETAILS"] = 1030] = "MASTER_WIRE_DETAILS";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_MELT"] = 1202] = "WALLET_COIN_MELT";
+ TalerSignaturePurpose[TalerSignaturePurpose["TEST"] = 4242] = "TEST";
+ TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_PAYMENT_OK"] = 1104] = "MERCHANT_PAYMENT_OK";
+ TalerSignaturePurpose[TalerSignaturePurpose["MERCHANT_CONTRACT"] = 1101] = "MERCHANT_CONTRACT";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_RECOUP"] = 1203] = "WALLET_COIN_RECOUP";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_LINK"] = 1204] = "WALLET_COIN_LINK";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_COIN_RECOUP_REFRESH"] = 1206] = "WALLET_COIN_RECOUP_REFRESH";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_AGE_ATTESTATION"] = 1207] = "WALLET_AGE_ATTESTATION";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_PURSE_CREATE"] = 1210] = "WALLET_PURSE_CREATE";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_PURSE_DEPOSIT"] = 1211] = "WALLET_PURSE_DEPOSIT";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_PURSE_MERGE"] = 1213] = "WALLET_PURSE_MERGE";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_ACCOUNT_MERGE"] = 1214] = "WALLET_ACCOUNT_MERGE";
+ TalerSignaturePurpose[TalerSignaturePurpose["WALLET_PURSE_ECONTRACT"] = 1216] = "WALLET_PURSE_ECONTRACT";
+ TalerSignaturePurpose[TalerSignaturePurpose["EXCHANGE_CONFIRM_RECOUP"] = 1039] = "EXCHANGE_CONFIRM_RECOUP";
+ TalerSignaturePurpose[TalerSignaturePurpose["EXCHANGE_CONFIRM_RECOUP_REFRESH"] = 1041] = "EXCHANGE_CONFIRM_RECOUP_REFRESH";
+ TalerSignaturePurpose[TalerSignaturePurpose["ANASTASIS_POLICY_UPLOAD"] = 1400] = "ANASTASIS_POLICY_UPLOAD";
+ TalerSignaturePurpose[TalerSignaturePurpose["ANASTASIS_POLICY_DOWNLOAD"] = 1401] = "ANASTASIS_POLICY_DOWNLOAD";
+ TalerSignaturePurpose[TalerSignaturePurpose["SYNC_BACKUP_UPLOAD"] = 1450] = "SYNC_BACKUP_UPLOAD";
+})(TalerSignaturePurpose || (TalerSignaturePurpose = {}));
+class SignaturePurposeBuilder {
+ constructor(purposeNum) {
+ this.purposeNum = purposeNum;
+ this.chunks = [];
+ }
+ put(bytes) {
+ this.chunks.push(Uint8Array.from(bytes));
+ return this;
+ }
+ build() {
+ let payloadLen = 0;
+ for (const c of this.chunks) {
+ payloadLen += c.byteLength;
+ }
+ const buf = new ArrayBuffer(4 + 4 + payloadLen);
+ const u8buf = new Uint8Array(buf);
+ let p = 8;
+ for (const c of this.chunks) {
+ u8buf.set(c, p);
+ p += c.byteLength;
+ }
+ const dvbuf = new DataView(buf);
+ dvbuf.setUint32(0, payloadLen + 4 + 4);
+ dvbuf.setUint32(4, this.purposeNum);
+ return u8buf;
+ }
+}
+function buildSigPS(purposeNum) {
+ return new SignaturePurposeBuilder(purposeNum);
+}
+/**
+ * Convert a big integer to a fixed-size, little-endian array.
+ */
+function bigintToNaclArr(x, size) {
+ const byteArr = new Uint8Array(size);
+ const arr = x.toArray(256).value.reverse();
+ byteArr.set(arr, 0);
+ return byteArr;
+}
+function bigintFromNaclArr(arr) {
+ let rev = new Uint8Array(arr);
+ rev = rev.reverse();
+ return bigint.fromArray(Array.from(rev), 256, false);
+}
+var Edx25519;
+(function (Edx25519) {
+ const revL = [
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
+ 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10,
+ ];
+ const L = bigint.fromArray(revL.reverse(), 256, false);
+ function keyCreateFromSeed(seed) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return crypto_edx25519_private_key_create_from_seed(seed);
+ });
+ }
+ Edx25519.keyCreateFromSeed = keyCreateFromSeed;
+ function keyCreate() {
+ return __awaiter(this, void 0, void 0, function* () {
+ return crypto_edx25519_private_key_create();
+ });
+ }
+ Edx25519.keyCreate = keyCreate;
+ function getPublic(priv) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return crypto_edx25519_get_public(priv);
+ });
+ }
+ Edx25519.getPublic = getPublic;
+ function sign(msg, key) {
+ throw Error("not implemented");
+ }
+ Edx25519.sign = sign;
+ function deriveFactor(pub, seed) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const res = kdfKw({
+ outputLength: 64,
+ salt: seed,
+ ikm: pub,
+ info: stringToBytes("edx25519-derivation"),
+ });
+ return res;
+ });
+ }
+ function privateKeyDerive(priv, seed) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const pub = yield getPublic(priv);
+ const privDec = priv;
+ const a = bigintFromNaclArr(privDec.subarray(0, 32));
+ const factorEnc = yield deriveFactor(pub, seed);
+ const factorModL = bigintFromNaclArr(factorEnc).mod(L);
+ const aPrime = a.divide(8).multiply(factorModL).mod(L).multiply(8).mod(L);
+ const bPrime = hash$1(typedArrayConcat([privDec.subarray(32, 64), factorEnc]))
+ .subarray(0, 32);
+ const newPriv = typedArrayConcat([bigintToNaclArr(aPrime, 32), bPrime]);
+ return newPriv;
+ });
+ }
+ Edx25519.privateKeyDerive = privateKeyDerive;
+ function publicKeyDerive(pub, seed) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const factorEnc = yield deriveFactor(pub, seed);
+ const factorReduced = crypto_core_ed25519_scalar_reduce(factorEnc);
+ const res = crypto_scalarmult_ed25519_noclamp(factorReduced, pub);
+ return res;
+ });
+ }
+ Edx25519.publicKeyDerive = publicKeyDerive;
+})(Edx25519 || (Edx25519 = {}));
+function invariant(cond) {
+ if (!cond) {
+ throw Error("invariant failed");
+ }
+}
+var AgeRestriction;
+(function (AgeRestriction) {
+ /**
+ * Smallest age value that the protocol considers "unrestricted".
+ */
+ AgeRestriction.AGE_UNRESTRICTED = 32;
+ function hashCommitment(ac) {
+ const hc = new HashState();
+ for (const pub of ac.publicKeys) {
+ hc.update(decodeCrock(pub));
+ }
+ return encodeCrock(hc.finish().subarray(0, 32));
+ }
+ AgeRestriction.hashCommitment = hashCommitment;
+ function countAgeGroups(mask) {
+ let count = 0;
+ let m = mask;
+ while (m > 0) {
+ count += m & 1;
+ m = m >> 1;
+ }
+ return count;
+ }
+ AgeRestriction.countAgeGroups = countAgeGroups;
+ /**
+ * Get the starting points for age groups in the mask.
+ */
+ function getAgeGroupsFromMask(mask) {
+ const groups = [];
+ let age = 1;
+ let m = mask >> 1;
+ while (m > 0) {
+ if (m & 1) {
+ groups.push(age);
+ }
+ m = m >> 1;
+ age++;
+ }
+ return groups;
+ }
+ AgeRestriction.getAgeGroupsFromMask = getAgeGroupsFromMask;
+ function getAgeGroupIndex(mask, age) {
+ invariant((mask & 1) === 1);
+ let i = 0;
+ let m = mask;
+ let a = age;
+ while (m > 0) {
+ if (a <= 0) {
+ break;
+ }
+ m = m >> 1;
+ i += m & 1;
+ a--;
+ }
+ return i;
+ }
+ AgeRestriction.getAgeGroupIndex = getAgeGroupIndex;
+ function ageGroupSpecToMask(ageGroupSpec) {
+ throw Error("not implemented");
+ }
+ AgeRestriction.ageGroupSpecToMask = ageGroupSpecToMask;
+ function restrictionCommit(ageMask, age) {
+ return __awaiter(this, void 0, void 0, function* () {
+ invariant((ageMask & 1) === 1);
+ const numPubs = countAgeGroups(ageMask) - 1;
+ const numPrivs = getAgeGroupIndex(ageMask, age);
+ const pubs = [];
+ const privs = [];
+ for (let i = 0; i < numPubs; i++) {
+ const priv = yield Edx25519.keyCreate();
+ const pub = yield Edx25519.getPublic(priv);
+ pubs.push(pub);
+ if (i < numPrivs) {
+ privs.push(priv);
+ }
+ }
+ return {
+ commitment: {
+ mask: ageMask,
+ publicKeys: pubs.map((x) => encodeCrock(x)),
+ },
+ proof: {
+ privateKeys: privs.map((x) => encodeCrock(x)),
+ },
+ };
+ });
+ }
+ AgeRestriction.restrictionCommit = restrictionCommit;
+ function restrictionCommitSeeded(ageMask, age, seed) {
+ return __awaiter(this, void 0, void 0, function* () {
+ invariant((ageMask & 1) === 1);
+ const numPubs = countAgeGroups(ageMask) - 1;
+ const numPrivs = getAgeGroupIndex(ageMask, age);
+ const pubs = [];
+ const privs = [];
+ for (let i = 0; i < numPubs; i++) {
+ const privSeed = yield kdfKw({
+ outputLength: 32,
+ ikm: seed,
+ info: stringToBytes("age-restriction-commit"),
+ salt: bufferForUint32(i),
+ });
+ const priv = yield Edx25519.keyCreateFromSeed(privSeed);
+ const pub = yield Edx25519.getPublic(priv);
+ pubs.push(pub);
+ if (i < numPrivs) {
+ privs.push(priv);
+ }
+ }
+ return {
+ commitment: {
+ mask: ageMask,
+ publicKeys: pubs.map((x) => encodeCrock(x)),
+ },
+ proof: {
+ privateKeys: privs.map((x) => encodeCrock(x)),
+ },
+ };
+ });
+ }
+ AgeRestriction.restrictionCommitSeeded = restrictionCommitSeeded;
+ /**
+ * Check that c1 = c2*salt
+ */
+ function commitCompare(c1, c2, salt) {
+ return __awaiter(this, void 0, void 0, function* () {
+ if (c1.publicKeys.length != c2.publicKeys.length) {
+ return false;
+ }
+ for (let i = 0; i < c1.publicKeys.length; i++) {
+ const k1 = decodeCrock(c1.publicKeys[i]);
+ const k2 = yield Edx25519.publicKeyDerive(decodeCrock(c2.publicKeys[i]), salt);
+ if (k1 != k2) {
+ return false;
+ }
+ }
+ return true;
+ });
+ }
+ AgeRestriction.commitCompare = commitCompare;
+ function commitmentDerive(commitmentProof, salt) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const newPrivs = [];
+ const newPubs = [];
+ for (const oldPub of commitmentProof.commitment.publicKeys) {
+ newPubs.push(yield Edx25519.publicKeyDerive(decodeCrock(oldPub), salt));
+ }
+ for (const oldPriv of commitmentProof.proof.privateKeys) {
+ newPrivs.push(yield Edx25519.privateKeyDerive(decodeCrock(oldPriv), salt));
+ }
+ return {
+ commitment: {
+ mask: commitmentProof.commitment.mask,
+ publicKeys: newPubs.map((x) => encodeCrock(x)),
+ },
+ proof: {
+ privateKeys: newPrivs.map((x) => encodeCrock(x)),
+ },
+ };
+ });
+ }
+ AgeRestriction.commitmentDerive = commitmentDerive;
+ function commitmentAttest(commitmentProof, age) {
+ const d = buildSigPS(TalerSignaturePurpose.WALLET_AGE_ATTESTATION)
+ .put(bufferForUint32(commitmentProof.commitment.mask))
+ .put(bufferForUint32(age))
+ .build();
+ const group = getAgeGroupIndex(commitmentProof.commitment.mask, age);
+ if (group === 0) {
+ // No attestation required.
+ return new Uint8Array(64);
+ }
+ const priv = commitmentProof.proof.privateKeys[group - 1];
+ const pub = commitmentProof.commitment.publicKeys[group - 1];
+ const sig = crypto_edx25519_sign_detached(d, decodeCrock(priv), decodeCrock(pub));
+ return sig;
+ }
+ AgeRestriction.commitmentAttest = commitmentAttest;
+ function commitmentVerify(commitment, sig, age) {
+ const d = buildSigPS(TalerSignaturePurpose.WALLET_AGE_ATTESTATION)
+ .put(bufferForUint32(commitment.mask))
+ .put(bufferForUint32(age))
+ .build();
+ const group = getAgeGroupIndex(commitment.mask, age);
+ if (group === 0) {
+ // No attestation required.
+ return true;
+ }
+ const pub = commitment.publicKeys[group - 1];
+ return crypto_edx25519_sign_detached_verify(d, decodeCrock(sig), decodeCrock(pub));
+ }
+ AgeRestriction.commitmentVerify = commitmentVerify;
+})(AgeRestriction || (AgeRestriction = {}));
+function deriveKey(keySeed, nonce, salt) {
+ return __awaiter(this, void 0, void 0, function* () {
+ return kdfKw({
+ outputLength: 32,
+ salt: nonce,
+ ikm: keySeed,
+ info: stringToBytes(salt),
+ });
+ });
+}
+function encryptWithDerivedKey(nonce, keySeed, plaintext, salt) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const key = yield deriveKey(keySeed, nonce, salt);
+ const cipherText = secretbox(plaintext, nonce, key);
+ return typedArrayConcat([nonce, cipherText]);
+ });
+}
+const nonceSize = 24;
+function decryptWithDerivedKey(ciphertext, keySeed, salt) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const ctBuf = ciphertext;
+ const nonceBuf = ctBuf.slice(0, nonceSize);
+ const enc = ctBuf.slice(nonceSize);
+ const key = yield deriveKey(keySeed, nonceBuf, salt);
+ const clearText = secretbox_open(enc, nonceBuf, key);
+ if (!clearText) {
+ throw Error("could not decrypt");
+ }
+ return clearText;
+ });
+}
+var ContractFormatTag;
+(function (ContractFormatTag) {
+ ContractFormatTag[ContractFormatTag["PaymentOffer"] = 0] = "PaymentOffer";
+ ContractFormatTag[ContractFormatTag["PaymentRequest"] = 1] = "PaymentRequest";
+})(ContractFormatTag || (ContractFormatTag = {}));
+const mergeSalt = "p2p-merge-contract";
+const depositSalt = "p2p-deposit-contract";
+function encryptContractForMerge(pursePub, contractPriv, mergePriv, contractTerms) {
+ const contractTermsCanon = canonicalJson(contractTerms) + "\0";
+ const contractTermsBytes = stringToBytes(contractTermsCanon);
+ const contractTermsCompressed = zlibSync(contractTermsBytes);
+ const data = typedArrayConcat([
+ bufferForUint32(ContractFormatTag.PaymentOffer),
+ bufferForUint32(contractTermsBytes.length),
+ mergePriv,
+ contractTermsCompressed,
+ ]);
+ const key = keyExchangeEcdheEddsa(contractPriv, pursePub);
+ return encryptWithDerivedKey(getRandomBytesF(24), key, data, mergeSalt);
+}
+function encryptContractForDeposit(pursePub, contractPriv, contractTerms) {
+ const contractTermsCanon = canonicalJson(contractTerms) + "\0";
+ const contractTermsBytes = stringToBytes(contractTermsCanon);
+ const contractTermsCompressed = zlibSync(contractTermsBytes);
+ const data = typedArrayConcat([
+ bufferForUint32(ContractFormatTag.PaymentRequest),
+ bufferForUint32(contractTermsBytes.length),
+ contractTermsCompressed,
+ ]);
+ const key = keyExchangeEcdheEddsa(contractPriv, pursePub);
+ return encryptWithDerivedKey(getRandomBytesF(24), key, data, depositSalt);
+}
+function decryptContractForMerge(enc, pursePub, contractPriv) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const key = keyExchangeEcdheEddsa(contractPriv, pursePub);
+ const dec = yield decryptWithDerivedKey(enc, key, mergeSalt);
+ const mergePriv = dec.slice(8, 8 + 32);
+ const contractTermsCompressed = dec.slice(8 + 32);
+ const contractTermsBuf = unzlibSync(contractTermsCompressed);
+ // Slice of the '\0' at the end and decode to a string
+ const contractTermsString = bytesToString(contractTermsBuf.slice(0, contractTermsBuf.length - 1));
+ return {
+ mergePriv: mergePriv,
+ contractTerms: JSON.parse(contractTermsString),
+ };
+ });
+}
+function decryptContractForDeposit(enc, pursePub, contractPriv) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const key = keyExchangeEcdheEddsa(contractPriv, pursePub);
+ const dec = yield decryptWithDerivedKey(enc, key, depositSalt);
+ const contractTermsCompressed = dec.slice(8);
+ const contractTermsBuf = unzlibSync(contractTermsCompressed);
+ // Slice of the '\0' at the end and decode to a string
+ const contractTermsString = bytesToString(contractTermsBuf.slice(0, contractTermsBuf.length - 1));
+ return {
+ contractTerms: JSON.parse(contractTermsString),
+ };
+ });
+}
+
+// Copyright (c) 2017, 2021 Pieter Wuille
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+var CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
+var GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
+const encodings = {
+ BECH32: "bech32",
+ BECH32M: "bech32m",
+};
+var bech32 = {
+ decode: decode$1,
+ encode: encode$2,
+ encodings: encodings,
+};
+function getEncodingConst(enc) {
+ if (enc == encodings.BECH32) {
+ return 1;
+ }
+ else if (enc == encodings.BECH32M) {
+ return 0x2bc830a3;
+ }
+ else {
+ throw new Error("unknown encoding");
+ }
+}
+function polymod(values) {
+ var chk = 1;
+ for (var p = 0; p < values.length; ++p) {
+ var top = chk >> 25;
+ chk = ((chk & 0x1ffffff) << 5) ^ values[p];
+ for (var i = 0; i < 5; ++i) {
+ if ((top >> i) & 1) {
+ chk ^= GENERATOR[i];
+ }
+ }
+ }
+ return chk;
+}
+function hrpExpand(hrp) {
+ var ret = [];
+ var p;
+ for (p = 0; p < hrp.length; ++p) {
+ ret.push(hrp.charCodeAt(p) >> 5);
+ }
+ ret.push(0);
+ for (p = 0; p < hrp.length; ++p) {
+ ret.push(hrp.charCodeAt(p) & 31);
+ }
+ return ret;
+}
+function verifyChecksum(hrp, data, enc) {
+ return polymod(hrpExpand(hrp).concat(data)) === getEncodingConst(enc);
+}
+function createChecksum(hrp, data, enc) {
+ var values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
+ var mod = polymod(values) ^ getEncodingConst(enc);
+ var ret = [];
+ for (var p = 0; p < 6; ++p) {
+ ret.push((mod >> (5 * (5 - p))) & 31);
+ }
+ return ret;
+}
+function encode$2(hrp, data, enc) {
+ var combined = data.concat(createChecksum(hrp, data, enc));
+ var ret = hrp + "1";
+ for (var p = 0; p < combined.length; ++p) {
+ ret += CHARSET.charAt(combined[p]);
+ }
+ return ret;
+}
+function decode$1(bechString, enc) {
+ var p;
+ var has_lower = false;
+ var has_upper = false;
+ for (p = 0; p < bechString.length; ++p) {
+ if (bechString.charCodeAt(p) < 33 || bechString.charCodeAt(p) > 126) {
+ return null;
+ }
+ if (bechString.charCodeAt(p) >= 97 && bechString.charCodeAt(p) <= 122) {
+ has_lower = true;
+ }
+ if (bechString.charCodeAt(p) >= 65 && bechString.charCodeAt(p) <= 90) {
+ has_upper = true;
+ }
+ }
+ if (has_lower && has_upper) {
+ return null;
+ }
+ bechString = bechString.toLowerCase();
+ var pos = bechString.lastIndexOf("1");
+ if (pos < 1 || pos + 7 > bechString.length || bechString.length > 90) {
+ return null;
+ }
+ var hrp = bechString.substring(0, pos);
+ var data = [];
+ for (p = pos + 1; p < bechString.length; ++p) {
+ var d = CHARSET.indexOf(bechString.charAt(p));
+ if (d === -1) {
+ return null;
+ }
+ data.push(d);
+ }
+ if (!verifyChecksum(hrp, data, enc)) {
+ return null;
+ }
+ return { hrp: hrp, data: data.slice(0, data.length - 6) };
+}
+
+// Copyright (c) 2017, 2021 Pieter Wuille
+var segwit_addr = {
+ encode: encode$1,
+ decode: decode,
+};
+function convertbits(data, frombits, tobits, pad) {
+ var acc = 0;
+ var bits = 0;
+ var ret = [];
+ var maxv = (1 << tobits) - 1;
+ for (var p = 0; p < data.length; ++p) {
+ var value = data[p];
+ if (value < 0 || value >> frombits !== 0) {
+ return []; //check this, was returning null
+ }
+ acc = (acc << frombits) | value;
+ bits += frombits;
+ while (bits >= tobits) {
+ bits -= tobits;
+ ret.push((acc >> bits) & maxv);
+ }
+ }
+ if (pad) {
+ if (bits > 0) {
+ ret.push((acc << (tobits - bits)) & maxv);
+ }
+ }
+ else if (bits >= frombits || (acc << (tobits - bits)) & maxv) {
+ return []; //check this, was returning null
+ }
+ return ret;
+}
+function decode(hrp, addr) {
+ var bech32m = false;
+ var dec = bech32.decode(addr, bech32.encodings.BECH32);
+ if (dec === null) {
+ dec = bech32.decode(addr, bech32.encodings.BECH32M);
+ bech32m = true;
+ }
+ if (dec === null ||
+ dec.hrp !== hrp ||
+ dec.data.length < 1 ||
+ dec.data[0] > 16) {
+ return null;
+ }
+ var res = convertbits(dec.data.slice(1), 5, 8, false);
+ if (res === null || res.length < 2 || res.length > 40) {
+ return null;
+ }
+ if (dec.data[0] === 0 && res.length !== 20 && res.length !== 32) {
+ return null;
+ }
+ if (dec.data[0] === 0 && bech32m) {
+ return null;
+ }
+ if (dec.data[0] !== 0 && !bech32m) {
+ return null;
+ }
+ return { version: dec.data[0], program: res };
+}
+function encode$1(hrp, version, program) {
+ var enc = bech32.encodings.BECH32;
+ if (version > 0) {
+ enc = bech32.encodings.BECH32M;
+ }
+ var ret = bech32.encode(hrp, [version].concat(convertbits(program, 8, 5, true)), enc);
+ if (decode(hrp, ret /*, enc*/) === null) {
+ return ""; //check this was returning null
+ }
+ return ret;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+function generateFakeSegwitAddress(reservePub, addr) {
+ if (!reservePub)
+ return [];
+ let pub;
+ try {
+ pub = decodeCrock(reservePub);
+ }
+ catch (_a) {
+ // pub = new Uint8Array(0)
+ }
+ if (!pub || pub.length !== 32)
+ return [];
+ const first_rnd = new Uint8Array(4);
+ first_rnd.set(pub.subarray(0, 4));
+ const second_rnd = new Uint8Array(4);
+ second_rnd.set(pub.subarray(0, 4));
+ first_rnd[0] = first_rnd[0] & 127;
+ second_rnd[0] = second_rnd[0] | 128;
+ const first_part = new Uint8Array(first_rnd.length + pub.length / 2);
+ first_part.set(first_rnd, 0);
+ first_part.set(pub.subarray(0, 16), 4);
+ const second_part = new Uint8Array(first_rnd.length + pub.length / 2);
+ second_part.set(second_rnd, 0);
+ second_part.set(pub.subarray(16, 32), 4);
+ const prefix = addr[0] === "t" && addr[1] == "b"
+ ? "tb"
+ : addr[0] === "b" && addr[1] == "c" && addr[2] === "r" && addr[3] == "t"
+ ? "bcrt"
+ : addr[0] === "b" && addr[1] == "c"
+ ? "bc"
+ : undefined;
+ if (prefix === undefined)
+ throw new Error("unknown bitcoin net");
+ const addr1 = segwit_addr.encode(prefix, 0, first_part);
+ const addr2 = segwit_addr.encode(prefix, 0, second_part);
+ return [addr1, addr2];
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+const paytoPfx = "payto://";
+/**
+ * Add query parameters to a payto URI
+ */
+function addPaytoQueryParams(s, params) {
+ const [acct, search] = s.slice(paytoPfx.length).split("?");
+ const searchParams = new URLSearchParams(search || "");
+ const keys = Object.keys(params);
+ if (keys.length === 0) {
+ return paytoPfx + acct;
+ }
+ for (const k of keys) {
+ searchParams.set(k, params[k]);
+ }
+ return paytoPfx + acct + "?" + searchParams.toString();
+}
+/**
+ * Parse a valid payto:// uri into a PaytoUri object
+ * RFC 8905
+ *
+ * @param s
+ * @returns
+ */
+function parsePaytoUri(s) {
+ if (!s.startsWith(paytoPfx)) {
+ return undefined;
+ }
+ const [acct, search] = s.slice(paytoPfx.length).split("?");
+ const firstSlashPos = acct.indexOf("/");
+ if (firstSlashPos === -1) {
+ return undefined;
+ }
+ const targetType = acct.slice(0, firstSlashPos);
+ const targetPath = acct.slice(firstSlashPos + 1);
+ const params = {};
+ const searchParams = new URLSearchParams(search || "");
+ searchParams.forEach((v, k) => {
+ params[k] = v;
+ });
+ if (targetType === "x-taler-bank") {
+ const parts = targetPath.split("/");
+ const host = parts[0];
+ const account = parts[1];
+ return {
+ targetPath,
+ targetType,
+ params,
+ isKnown: true,
+ host,
+ account,
+ };
+ }
+ if (targetType === "iban") {
+ return {
+ isKnown: true,
+ targetPath,
+ targetType,
+ params,
+ iban: targetPath,
+ };
+ }
+ if (targetType === "bitcoin") {
+ const msg = /\b([A-Z0-9]{52})\b/.exec(params["message"]);
+ const reserve = !msg ? params["subject"] : msg[0];
+ const segwitAddrs = !reserve
+ ? []
+ : generateFakeSegwitAddress(reserve, targetPath);
+ const result = {
+ isKnown: true,
+ targetPath,
+ targetType,
+ params,
+ segwitAddrs,
+ };
+ return result;
+ }
+ return {
+ targetPath,
+ targetType,
+ params,
+ isKnown: false,
+ };
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+const codecForReserveStatus = () => buildCodecForObject()
+ .property("balance", codecForString())
+ .build("ReserveStatus");
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var ReserveTransactionType;
+(function (ReserveTransactionType) {
+ ReserveTransactionType["Withdraw"] = "WITHDRAW";
+ ReserveTransactionType["Credit"] = "CREDIT";
+ ReserveTransactionType["Recoup"] = "RECOUP";
+ ReserveTransactionType["Closing"] = "CLOSING";
+})(ReserveTransactionType || (ReserveTransactionType = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2019-2020 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Parse a taler[+http]://withdraw URI.
+ * Return undefined if not passed a valid URI.
+ */
+function parseWithdrawUri(s) {
+ const pi = parseProtoInfo(s, "withdraw");
+ if (!pi) {
+ return undefined;
+ }
+ const parts = pi.rest.split("/");
+ if (parts.length < 2) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ const pathSegments = parts.slice(1, parts.length - 1);
+ /**
+ * The statement below does not tolerate a slash-ended URI.
+ * This results in (1) the withdrawalId being passed as the
+ * empty string, and (2) the bankIntegrationApi ending with the
+ * actual withdrawal operation ID. That can be fixed by
+ * trimming the parts-list. FIXME
+ */
+ const withdrawId = parts[parts.length - 1];
+ const p = [host, ...pathSegments].join("/");
+ return {
+ bankIntegrationApiBaseUrl: canonicalizeBaseUrl(`${pi.innerProto}://${p}/`),
+ withdrawalOperationId: withdrawId,
+ };
+}
+var TalerUriType;
+(function (TalerUriType) {
+ TalerUriType["TalerPay"] = "taler-pay";
+ TalerUriType["TalerWithdraw"] = "taler-withdraw";
+ TalerUriType["TalerTip"] = "taler-tip";
+ TalerUriType["TalerRefund"] = "taler-refund";
+ TalerUriType["TalerNotifyReserve"] = "taler-notify-reserve";
+ TalerUriType["TalerPayPush"] = "taler-pay-push";
+ TalerUriType["TalerPayPull"] = "taler-pay-pull";
+ TalerUriType["TalerRecovery"] = "taler-recovery";
+ TalerUriType["TalerDevExperiment"] = "taler-dev-experiment";
+ TalerUriType["Unknown"] = "unknown";
+})(TalerUriType || (TalerUriType = {}));
+const talerActionPayPull = "pay-pull";
+const talerActionPayPush = "pay-push";
+function parseProtoInfo(s, action) {
+ const pfxPlain = `taler://${action}/`;
+ const pfxHttp = `taler+http://${action}/`;
+ if (s.toLowerCase().startsWith(pfxPlain)) {
+ return {
+ innerProto: "https",
+ rest: s.substring(pfxPlain.length),
+ };
+ }
+ else if (s.toLowerCase().startsWith(pfxHttp)) {
+ return {
+ innerProto: "http",
+ rest: s.substring(pfxHttp.length),
+ };
+ }
+ else {
+ return undefined;
+ }
+}
+/**
+ * Parse a taler[+http]://pay URI.
+ * Return undefined if not passed a valid URI.
+ */
+function parsePayUri(s) {
+ var _a, _b, _c;
+ const pi = parseProtoInfo(s, "pay");
+ if (!pi) {
+ return undefined;
+ }
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ const q = new URLSearchParams((_a = c[1]) !== null && _a !== void 0 ? _a : "");
+ const claimToken = (_b = q.get("c")) !== null && _b !== void 0 ? _b : undefined;
+ const noncePriv = (_c = q.get("n")) !== null && _c !== void 0 ? _c : undefined;
+ const parts = c[0].split("/");
+ if (parts.length < 3) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ const sessionId = parts[parts.length - 1];
+ const orderId = parts[parts.length - 2];
+ const pathSegments = parts.slice(1, parts.length - 2);
+ const p = [host, ...pathSegments].join("/");
+ const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
+ return {
+ merchantBaseUrl,
+ orderId,
+ sessionId: sessionId,
+ claimToken,
+ noncePriv,
+ };
+}
+function parsePayPushUri(s) {
+ const pi = parseProtoInfo(s, talerActionPayPush);
+ if (!pi) {
+ return undefined;
+ }
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ const parts = c[0].split("/");
+ if (parts.length < 2) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ const contractPriv = parts[parts.length - 1];
+ const pathSegments = parts.slice(1, parts.length - 1);
+ const p = [host, ...pathSegments].join("/");
+ const exchangeBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
+ return {
+ exchangeBaseUrl,
+ contractPriv,
+ };
+}
+function parsePayPullUri(s) {
+ const pi = parseProtoInfo(s, talerActionPayPull);
+ if (!pi) {
+ return undefined;
+ }
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ const parts = c[0].split("/");
+ if (parts.length < 2) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ const contractPriv = parts[parts.length - 1];
+ const pathSegments = parts.slice(1, parts.length - 1);
+ const p = [host, ...pathSegments].join("/");
+ const exchangeBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
+ return {
+ exchangeBaseUrl,
+ contractPriv,
+ };
+}
+/**
+ * Parse a taler[+http]://tip URI.
+ * Return undefined if not passed a valid URI.
+ */
+function parseTipUri(s) {
+ const pi = parseProtoInfo(s, "tip");
+ if (!pi) {
+ return undefined;
+ }
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ const parts = c[0].split("/");
+ if (parts.length < 2) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ const tipId = parts[parts.length - 1];
+ const pathSegments = parts.slice(1, parts.length - 1);
+ const p = [host, ...pathSegments].join("/");
+ const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
+ return {
+ merchantBaseUrl,
+ merchantTipId: tipId,
+ };
+}
+/**
+ * Parse a taler[+http]://refund URI.
+ * Return undefined if not passed a valid URI.
+ */
+function parseRefundUri(s) {
+ const pi = parseProtoInfo(s, "refund");
+ if (!pi) {
+ return undefined;
+ }
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ const parts = c[0].split("/");
+ if (parts.length < 3) {
+ return undefined;
+ }
+ const host = parts[0].toLowerCase();
+ parts[parts.length - 1];
+ const orderId = parts[parts.length - 2];
+ const pathSegments = parts.slice(1, parts.length - 2);
+ const p = [host, ...pathSegments].join("/");
+ const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
+ return {
+ merchantBaseUrl,
+ orderId,
+ };
+}
+function parseDevExperimentUri(s) {
+ const pi = parseProtoInfo(s, "dev-experiment");
+ const c = pi === null || pi === void 0 ? void 0 : pi.rest.split("?");
+ if (!c) {
+ return undefined;
+ }
+ // const q = new URLSearchParams(c[1] ?? "");
+ const parts = c[0].split("/");
+ return {
+ devExperimentId: parts[0],
+ };
+}
+function constructPayPushUri(args) {
+ const url = new URL$1(args.exchangeBaseUrl);
+ let proto;
+ if (url.protocol === "https:") {
+ proto = "taler";
+ }
+ else if (url.protocol === "http:") {
+ proto = "taler+http";
+ }
+ else {
+ throw Error(`Unsupported exchange URL protocol ${args.exchangeBaseUrl}`);
+ }
+ if (!url.pathname.endsWith("/")) {
+ throw Error(`exchange base URL must end with a slash (got ${args.exchangeBaseUrl}instead)`);
+ }
+ return `${proto}://pay-push/${url.host}${url.pathname}${args.contractPriv}`;
+}
+function constructPayPullUri(args) {
+ const url = new URL$1(args.exchangeBaseUrl);
+ let proto;
+ if (url.protocol === "https:") {
+ proto = "taler";
+ }
+ else if (url.protocol === "http:") {
+ proto = "taler+http";
+ }
+ else {
+ throw Error(`Unsupported exchange URL protocol ${args.exchangeBaseUrl}`);
+ }
+ if (!url.pathname.endsWith("/")) {
+ throw Error(`exchange base URL must end with a slash (got ${args.exchangeBaseUrl}instead)`);
+ }
+ return `${proto}://pay-pull/${url.host}${url.pathname}${args.contractPriv}`;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var TransactionType;
+(function (TransactionType) {
+ TransactionType["Withdrawal"] = "withdrawal";
+ TransactionType["Payment"] = "payment";
+ TransactionType["Refund"] = "refund";
+ TransactionType["Refresh"] = "refresh";
+ TransactionType["Tip"] = "tip";
+ TransactionType["Deposit"] = "deposit";
+ TransactionType["PeerPushDebit"] = "peer-push-debit";
+ TransactionType["PeerPushCredit"] = "peer-push-credit";
+ TransactionType["PeerPullDebit"] = "peer-pull-debit";
+ TransactionType["PeerPullCredit"] = "peer-pull-credit";
+})(TransactionType || (TransactionType = {}));
+var WithdrawalType;
+(function (WithdrawalType) {
+ WithdrawalType["TalerBankIntegrationApi"] = "taler-bank-integration-api";
+ WithdrawalType["ManualTransfer"] = "manual-transfer";
+})(WithdrawalType || (WithdrawalType = {}));
+var PaymentStatus;
+(function (PaymentStatus) {
+ /**
+ * Explicitly aborted after timeout / failure
+ */
+ PaymentStatus["Aborted"] = "aborted";
+ /**
+ * Payment failed, wallet will auto-retry.
+ * User should be given the option to retry now / abort.
+ */
+ PaymentStatus["Failed"] = "failed";
+ /**
+ * Paid successfully
+ */
+ PaymentStatus["Paid"] = "paid";
+ /**
+ * User accepted, payment is processing.
+ */
+ PaymentStatus["Accepted"] = "accepted";
+})(PaymentStatus || (PaymentStatus = {}));
+const codecForTransactionByIdRequest = () => buildCodecForObject()
+ .property("transactionId", codecForString())
+ .build("TransactionByIdRequest");
+const codecForTransactionsRequest = () => buildCodecForObject()
+ .property("currency", codecOptional(codecForString()))
+ .property("search", codecOptional(codecForString()))
+ .build("TransactionsRequest");
+
+/*
+ This file is part of GNU Taler
+ (C) 2015-2020 Taler Systems SA
+
+ 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/>
+ */
+/**
+ * Status of a coin.
+ */
+var CoinStatus;
+(function (CoinStatus) {
+ /**
+ * Withdrawn and never shown to anybody.
+ */
+ CoinStatus["Fresh"] = "fresh";
+ /**
+ * Fresh, but currently marked as "suspended", thus won't be used
+ * for spending. Used for testing.
+ */
+ CoinStatus["FreshSuspended"] = "fresh-suspended";
+ /**
+ * A coin that has been spent and refreshed.
+ */
+ CoinStatus["Dormant"] = "dormant";
+})(CoinStatus || (CoinStatus = {}));
+var ConfirmPayResultType;
+(function (ConfirmPayResultType) {
+ ConfirmPayResultType["Done"] = "done";
+ ConfirmPayResultType["Pending"] = "pending";
+})(ConfirmPayResultType || (ConfirmPayResultType = {}));
+var PreparePayResultType;
+(function (PreparePayResultType) {
+ PreparePayResultType["PaymentPossible"] = "payment-possible";
+ PreparePayResultType["InsufficientBalance"] = "insufficient-balance";
+ PreparePayResultType["AlreadyConfirmed"] = "already-confirmed";
+})(PreparePayResultType || (PreparePayResultType = {}));
+/**
+ * Reasons for why a coin is being refreshed.
+ */
+var RefreshReason;
+(function (RefreshReason) {
+ RefreshReason["Manual"] = "manual";
+ RefreshReason["PayMerchant"] = "pay-merchant";
+ RefreshReason["PayDeposit"] = "pay-deposit";
+ RefreshReason["PayPeerPush"] = "pay-peer-push";
+ RefreshReason["PayPeerPull"] = "pay-peer-pull";
+ RefreshReason["Refund"] = "refund";
+ RefreshReason["AbortPay"] = "abort-pay";
+ RefreshReason["Recoup"] = "recoup";
+ RefreshReason["BackupRestored"] = "backup-restored";
+ RefreshReason["Scheduled"] = "scheduled";
+})(RefreshReason || (RefreshReason = {}));
+var ExchangeTosStatus;
+(function (ExchangeTosStatus) {
+ ExchangeTosStatus["New"] = "new";
+ ExchangeTosStatus["Accepted"] = "accepted";
+ ExchangeTosStatus["Changed"] = "changed";
+ ExchangeTosStatus["NotFound"] = "not-found";
+ ExchangeTosStatus["Unknown"] = "unknown";
+})(ExchangeTosStatus || (ExchangeTosStatus = {}));
+var ExchangeEntryStatus;
+(function (ExchangeEntryStatus) {
+ ExchangeEntryStatus["Unknown"] = "unknown";
+ ExchangeEntryStatus["Outdated"] = "outdated";
+ ExchangeEntryStatus["Ok"] = "ok";
+})(ExchangeEntryStatus || (ExchangeEntryStatus = {}));
+const codecForTestPayArgs = () => buildCodecForObject()
+ .property("merchantBaseUrl", codecForString())
+ .property("merchantAuthToken", codecOptional(codecForString()))
+ .property("amount", codecForString())
+ .property("summary", codecForString())
+ .property("forcedCoinSel", codecForAny())
+ .build("TestPayArgs");
+const codecForIntegrationTestArgs = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("bankBaseUrl", codecForString())
+ .property("merchantBaseUrl", codecForString())
+ .property("merchantAuthToken", codecOptional(codecForString()))
+ .property("amountToSpend", codecForAmountString())
+ .property("amountToWithdraw", codecForAmountString())
+ .property("bankAccessApiBaseUrl", codecOptional(codecForAmountString()))
+ .build("IntegrationTestArgs");
+const codecForAddExchangeRequest = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("forceUpdate", codecOptional(codecForBoolean()))
+ .build("AddExchangeRequest");
+const codecForGetExchangeTosRequest = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("acceptedFormat", codecOptional(codecForList(codecForString())))
+ .build("GetExchangeTosRequest");
+const codecForAcceptManualWithdrawalRequet = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("amount", codecForString())
+ .property("restrictAge", codecOptional(codecForNumber()))
+ .build("AcceptManualWithdrawalRequest");
+const codecForAcceptBankIntegratedWithdrawalRequest = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("talerWithdrawUri", codecForString())
+ .property("forcedDenomSel", codecForAny())
+ .property("restrictAge", codecOptional(codecForNumber()))
+ .build("AcceptBankIntegratedWithdrawalRequest");
+const codecForGetWithdrawalDetailsForAmountRequest = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("amount", codecForString())
+ .property("restrictAge", codecOptional(codecForNumber()))
+ .build("GetWithdrawalDetailsForAmountRequest");
+const codecForAcceptExchangeTosRequest = () => buildCodecForObject()
+ .property("exchangeBaseUrl", codecForString())
+ .property("etag", codecOptional(codecForString()))
+ .build("AcceptExchangeTosRequest");
+const codecForApplyRefundRequest = () => buildCodecForObject()
+ .property("talerRefundUri", codecForString())
+ .build("ApplyRefundRequest");
+const codecForApplyRefundFromPurchaseIdRequest = () => buildCodecForObject()
+ .property("purchaseId", codecForString())
+ .build("ApplyRefundFromPurchaseIdRequest");
+const codecForGetWithdrawalDetailsForUri = () => buildCodecForObject()
+ .property("talerWithdrawUri", codecForString())
+ .property("restrictAge", codecOptional(codecForNumber()))
+ .build("GetWithdrawalDetailsForUriRequest");
+const codecForListKnownBankAccounts = () => buildCodecForObject()
+ .property("currency", codecOptional(codecForString()))
+ .build("ListKnownBankAccountsRequest");
+const codecForAddKnownBankAccounts = () => buildCodecForObject()
+ .property("payto", codecForString())
+ .property("alias", codecForString())
+ .property("currency", codecForString())
+ .build("AddKnownBankAccountsRequest");
+const codecForForgetKnownBankAccounts = () => buildCodecForObject()
+ .property("payto", codecForString())
+ .build("ForgetKnownBankAccountsRequest");
+const codecForGetContractTermsDetails = () => buildCodecForObject()
+ .property("proposalId", codecForString())
+ .build("GetContractTermsDetails");
+const codecForPreparePayRequest = () => buildCodecForObject()
+ .property("talerPayUri", codecForString())
+ .build("PreparePay");
+const codecForConfirmPayRequest = () => buildCodecForObject()
+ .property("proposalId", codecForString())
+ .property("sessionId", codecOptional(codecForString()))
+ .property("forcedCoinSel", codecForAny())
+ .build("ConfirmPay");
+/**
+ * Strategy for loading recovery information.
+ */
+var RecoveryMergeStrategy;
+(function (RecoveryMergeStrategy) {
+ /**
+ * Keep the local wallet root key, import and take over providers.
+ */
+ RecoveryMergeStrategy["Ours"] = "ours";
+ /**
+ * Migrate to the wallet root key from the recovery information.
+ */
+ RecoveryMergeStrategy["Theirs"] = "theirs";
+})(RecoveryMergeStrategy || (RecoveryMergeStrategy = {}));
+const codecForWithdrawTestBalance = () => buildCodecForObject()
+ .property("amount", codecForString())
+ .property("bankBaseUrl", codecForString())
+ .property("exchangeBaseUrl", codecForString())
+ .property("forcedDenomSel", codecForAny())
+ .property("bankAccessApiBaseUrl", codecOptional(codecForString()))
+ .build("WithdrawTestBalanceRequest");
+const codecForSetCoinSuspendedRequest = () => buildCodecForObject()
+ .property("coinPub", codecForString())
+ .property("suspended", codecForBoolean())
+ .build("SetCoinSuspendedRequest");
+const codecForForceRefreshRequest = () => buildCodecForObject()
+ .property("coinPubList", codecForList(codecForString()))
+ .build("ForceRefreshRequest");
+const codecForPrepareRefundRequest = () => buildCodecForObject()
+ .property("talerRefundUri", codecForString())
+ .build("PrepareRefundRequest");
+const codecForPrepareTipRequest = () => buildCodecForObject()
+ .property("talerTipUri", codecForString())
+ .build("PrepareTipRequest");
+const codecForAcceptTipRequest = () => buildCodecForObject()
+ .property("walletTipId", codecForString())
+ .build("AcceptTipRequest");
+const codecForAbortPayWithRefundRequest = () => buildCodecForObject()
+ .property("proposalId", codecForString())
+ .build("AbortPayWithRefundRequest");
+const codecForGetFeeForDeposit = () => buildCodecForObject()
+ .property("amount", codecForAmountString())
+ .property("depositPaytoUri", codecForString())
+ .build("GetFeeForDepositRequest");
+const codecForPrepareDepositRequest = () => buildCodecForObject()
+ .property("amount", codecForAmountString())
+ .property("depositPaytoUri", codecForString())
+ .build("PrepareDepositRequest");
+const codecForCreateDepositGroupRequest = () => buildCodecForObject()
+ .property("amount", codecForAmountString())
+ .property("depositPaytoUri", codecForString())
+ .build("CreateDepositGroupRequest");
+const codecForTrackDepositGroupRequest = () => buildCodecForObject()
+ .property("depositGroupId", codecForAmountString())
+ .build("TrackDepositGroupRequest");
+const codecForDeleteTransactionRequest = () => buildCodecForObject()
+ .property("transactionId", codecForString())
+ .build("DeleteTransactionRequest");
+const codecForRetryTransactionRequest = () => buildCodecForObject()
+ .property("transactionId", codecForString())
+ .build("RetryTransactionRequest");
+const codecForSetWalletDeviceIdRequest = () => buildCodecForObject()
+ .property("walletDeviceId", codecForString())
+ .build("SetWalletDeviceIdRequest");
+const codecForWithdrawFakebankRequest = () => buildCodecForObject()
+ .property("amount", codecForAmountString())
+ .property("bank", codecForString())
+ .property("exchange", codecForString())
+ .build("WithdrawFakebankRequest");
+const codecForImportDbRequest = () => buildCodecForObject()
+ .property("dump", codecForAny())
+ .build("ImportDbRequest");
+const codecForInitiatePeerPushPaymentRequest = () => buildCodecForObject()
+ .property("amount", codecForAmountString())
+ .property("partialContractTerms", codecForAny())
+ .build("InitiatePeerPushPaymentRequest");
+const codecForCheckPeerPushPaymentRequest = () => buildCodecForObject()
+ .property("talerUri", codecForString())
+ .build("CheckPeerPushPaymentRequest");
+const codecForCheckPeerPullPaymentRequest = () => buildCodecForObject()
+ .property("talerUri", codecForString())
+ .build("CheckPeerPullPaymentRequest");
+const codecForAcceptPeerPushPaymentRequest = () => buildCodecForObject()
+ .property("peerPushPaymentIncomingId", codecForString())
+ .build("AcceptPeerPushPaymentRequest");
+const codecForSetDevModeRequest = () => buildCodecForObject()
+ .property("devModeEnabled", codecForBoolean())
+ .build("SetDevModeRequest");
+const codecForApplyDevExperiment = () => buildCodecForObject()
+ .property("devExperimentUri", codecForString())
+ .build("ApplyDevExperimentRequest");
+const codecForAcceptPeerPullPaymentRequest = () => buildCodecForObject()
+ .property("peerPullPaymentIncomingId", codecForString())
+ .build("AcceptPeerPllPaymentRequest");
+const codecForInitiatePeerPullPaymentRequest = () => buildCodecForObject()
+ .property("partialContractTerms", codecForAny())
+ .property("amount", codecForAmountString())
+ .property("exchangeBaseUrl", codecForAmountString())
+ .build("InitiatePeerPullPaymentRequest");
+
+var jed = {exports: {}};
+
+/**
+ * @preserve jed.js https://github.com/SlexAxton/Jed
+ */
+
+(function (module, exports) {
+ /*
+ -----------
+ A gettext compatible i18n library for modern JavaScript Applications
+
+ by Alex Sexton - AlexSexton [at] gmail - @SlexAxton
+
+ MIT License
+
+ A jQuery Foundation project - requires CLA to contribute -
+ https://contribute.jquery.org/CLA/
+
+
+
+ Jed offers the entire applicable GNU gettext spec'd set of
+ functions, but also offers some nicer wrappers around them.
+ The api for gettext was written for a language with no function
+ overloading, so Jed allows a little more of that.
+
+ Many thanks to Joshua I. Miller - unrtst@cpan.org - who wrote
+ gettext.js back in 2008. I was able to vet a lot of my ideas
+ against his. I also made sure Jed passed against his tests
+ in order to offer easy upgrades -- jsgettext.berlios.de
+ */
+ (function (root, undef) {
+
+ // Set up some underscore-style functions, if you already have
+ // underscore, feel free to delete this section, and use it
+ // directly, however, the amount of functions used doesn't
+ // warrant having underscore as a full dependency.
+ // Underscore 1.3.0 was used to port and is licensed
+ // under the MIT License by Jeremy Ashkenas.
+ var ArrayProto = Array.prototype,
+ ObjProto = Object.prototype,
+ slice = ArrayProto.slice,
+ hasOwnProp = ObjProto.hasOwnProperty,
+ nativeForEach = ArrayProto.forEach,
+ breaker = {};
+
+ // We're not using the OOP style _ so we don't need the
+ // extra level of indirection. This still means that you
+ // sub out for real `_` though.
+ var _ = {
+ forEach : function( obj, iterator, context ) {
+ var i, l, key;
+ if ( obj === null ) {
+ return;
+ }
+
+ if ( nativeForEach && obj.forEach === nativeForEach ) {
+ obj.forEach( iterator, context );
+ }
+ else if ( obj.length === +obj.length ) {
+ for ( i = 0, l = obj.length; i < l; i++ ) {
+ if ( i in obj && iterator.call( context, obj[i], i, obj ) === breaker ) {
+ return;
+ }
+ }
+ }
+ else {
+ for ( key in obj) {
+ if ( hasOwnProp.call( obj, key ) ) {
+ if ( iterator.call (context, obj[key], key, obj ) === breaker ) {
+ return;
+ }
+ }
+ }
+ }
+ },
+ extend : function( obj ) {
+ this.forEach( slice.call( arguments, 1 ), function ( source ) {
+ for ( var prop in source ) {
+ obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ }
+ };
+ // END Miniature underscore impl
+
+ // Jed is a constructor function
+ var Jed = function ( options ) {
+ // Some minimal defaults
+ this.defaults = {
+ "locale_data" : {
+ "messages" : {
+ "" : {
+ "domain" : "messages",
+ "lang" : "en",
+ "plural_forms" : "nplurals=2; plural=(n != 1);"
+ }
+ // There are no default keys, though
+ }
+ },
+ // The default domain if one is missing
+ "domain" : "messages",
+ // enable debug mode to log untranslated strings to the console
+ "debug" : false
+ };
+
+ // Mix in the sent options with the default options
+ this.options = _.extend( {}, this.defaults, options );
+ this.textdomain( this.options.domain );
+
+ if ( options.domain && ! this.options.locale_data[ this.options.domain ] ) {
+ throw new Error('Text domain set to non-existent domain: `' + options.domain + '`');
+ }
+ };
+
+ // The gettext spec sets this character as the default
+ // delimiter for context lookups.
+ // e.g.: context\u0004key
+ // If your translation company uses something different,
+ // just change this at any time and it will use that instead.
+ Jed.context_delimiter = String.fromCharCode( 4 );
+
+ function getPluralFormFunc ( plural_form_string ) {
+ return Jed.PF.compile( plural_form_string || "nplurals=2; plural=(n != 1);");
+ }
+
+ function Chain( key, i18n ){
+ this._key = key;
+ this._i18n = i18n;
+ }
+
+ // Create a chainable api for adding args prettily
+ _.extend( Chain.prototype, {
+ onDomain : function ( domain ) {
+ this._domain = domain;
+ return this;
+ },
+ withContext : function ( context ) {
+ this._context = context;
+ return this;
+ },
+ ifPlural : function ( num, pkey ) {
+ this._val = num;
+ this._pkey = pkey;
+ return this;
+ },
+ fetch : function ( sArr ) {
+ if ( {}.toString.call( sArr ) != '[object Array]' ) {
+ sArr = [].slice.call(arguments, 0);
+ }
+ return ( sArr && sArr.length ? Jed.sprintf : function(x){ return x; } )(
+ this._i18n.dcnpgettext(this._domain, this._context, this._key, this._pkey, this._val),
+ sArr
+ );
+ }
+ });
+
+ // Add functions to the Jed prototype.
+ // These will be the functions on the object that's returned
+ // from creating a `new Jed()`
+ // These seem redundant, but they gzip pretty well.
+ _.extend( Jed.prototype, {
+ // The sexier api start point
+ translate : function ( key ) {
+ return new Chain( key, this );
+ },
+
+ textdomain : function ( domain ) {
+ if ( ! domain ) {
+ return this._textdomain;
+ }
+ this._textdomain = domain;
+ },
+
+ gettext : function ( key ) {
+ return this.dcnpgettext.call( this, undef, undef, key );
+ },
+
+ dgettext : function ( domain, key ) {
+ return this.dcnpgettext.call( this, domain, undef, key );
+ },
+
+ dcgettext : function ( domain , key /*, category */ ) {
+ // Ignores the category anyways
+ return this.dcnpgettext.call( this, domain, undef, key );
+ },
+
+ ngettext : function ( skey, pkey, val ) {
+ return this.dcnpgettext.call( this, undef, undef, skey, pkey, val );
+ },
+
+ dngettext : function ( domain, skey, pkey, val ) {
+ return this.dcnpgettext.call( this, domain, undef, skey, pkey, val );
+ },
+
+ dcngettext : function ( domain, skey, pkey, val/*, category */) {
+ return this.dcnpgettext.call( this, domain, undef, skey, pkey, val );
+ },
+
+ pgettext : function ( context, key ) {
+ return this.dcnpgettext.call( this, undef, context, key );
+ },
+
+ dpgettext : function ( domain, context, key ) {
+ return this.dcnpgettext.call( this, domain, context, key );
+ },
+
+ dcpgettext : function ( domain, context, key/*, category */) {
+ return this.dcnpgettext.call( this, domain, context, key );
+ },
+
+ npgettext : function ( context, skey, pkey, val ) {
+ return this.dcnpgettext.call( this, undef, context, skey, pkey, val );
+ },
+
+ dnpgettext : function ( domain, context, skey, pkey, val ) {
+ return this.dcnpgettext.call( this, domain, context, skey, pkey, val );
+ },
+
+ // The most fully qualified gettext function. It has every option.
+ // Since it has every option, we can use it from every other method.
+ // This is the bread and butter.
+ // Technically there should be one more argument in this function for 'Category',
+ // but since we never use it, we might as well not waste the bytes to define it.
+ dcnpgettext : function ( domain, context, singular_key, plural_key, val ) {
+ // Set some defaults
+
+ plural_key = plural_key || singular_key;
+
+ // Use the global domain default if one
+ // isn't explicitly passed in
+ domain = domain || this._textdomain;
+
+ var fallback;
+
+ // Handle special cases
+
+ // No options found
+ if ( ! this.options ) {
+ // There's likely something wrong, but we'll return the correct key for english
+ // We do this by instantiating a brand new Jed instance with the default set
+ // for everything that could be broken.
+ fallback = new Jed();
+ return fallback.dcnpgettext.call( fallback, undefined, undefined, singular_key, plural_key, val );
+ }
+
+ // No translation data provided
+ if ( ! this.options.locale_data ) {
+ throw new Error('No locale data provided.');
+ }
+
+ if ( ! this.options.locale_data[ domain ] ) {
+ throw new Error('Domain `' + domain + '` was not found.');
+ }
+
+ if ( ! this.options.locale_data[ domain ][ "" ] ) {
+ throw new Error('No locale meta information provided.');
+ }
+
+ // Make sure we have a truthy key. Otherwise we might start looking
+ // into the empty string key, which is the options for the locale
+ // data.
+ if ( ! singular_key ) {
+ throw new Error('No translation key found.');
+ }
+
+ var key = context ? context + Jed.context_delimiter + singular_key : singular_key,
+ locale_data = this.options.locale_data,
+ dict = locale_data[ domain ],
+ defaultConf = (locale_data.messages || this.defaults.locale_data.messages)[""],
+ pluralForms = dict[""].plural_forms || dict[""]["Plural-Forms"] || dict[""]["plural-forms"] || defaultConf.plural_forms || defaultConf["Plural-Forms"] || defaultConf["plural-forms"],
+ val_list,
+ res;
+
+ var val_idx;
+ if (val === undefined) {
+ // No value passed in; assume singular key lookup.
+ val_idx = 0;
+
+ } else {
+ // Value has been passed in; use plural-forms calculations.
+
+ // Handle invalid numbers, but try casting strings for good measure
+ if ( typeof val != 'number' ) {
+ val = parseInt( val, 10 );
+
+ if ( isNaN( val ) ) {
+ throw new Error('The number that was passed in is not a number.');
+ }
+ }
+
+ val_idx = getPluralFormFunc(pluralForms)(val);
+ }
+
+ // Throw an error if a domain isn't found
+ if ( ! dict ) {
+ throw new Error('No domain named `' + domain + '` could be found.');
+ }
+
+ val_list = dict[ key ];
+
+ // If there is no match, then revert back to
+ // english style singular/plural with the keys passed in.
+ if ( ! val_list || val_idx > val_list.length ) {
+ if (this.options.missing_key_callback) {
+ this.options.missing_key_callback(key, domain);
+ }
+ res = [ singular_key, plural_key ];
+
+ // collect untranslated strings
+ if (this.options.debug===true) {
+ console.log(res[ getPluralFormFunc(pluralForms)( val ) ]);
+ }
+ return res[ getPluralFormFunc()( val ) ];
+ }
+
+ res = val_list[ val_idx ];
+
+ // This includes empty strings on purpose
+ if ( ! res ) {
+ res = [ singular_key, plural_key ];
+ return res[ getPluralFormFunc()( val ) ];
+ }
+ return res;
+ }
+ });
+
+
+ // We add in sprintf capabilities for post translation value interolation
+ // This is not internally used, so you can remove it if you have this
+ // available somewhere else, or want to use a different system.
+
+ // We _slightly_ modify the normal sprintf behavior to more gracefully handle
+ // undefined values.
+
+ /**
+ sprintf() for JavaScript 0.7-beta1
+ http://www.diveintojavascript.com/projects/javascript-sprintf
+
+ Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of sprintf() for JavaScript nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ var sprintf = (function() {
+ function get_type(variable) {
+ return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
+ }
+ function str_repeat(input, multiplier) {
+ for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
+ return output.join('');
+ }
+
+ var str_format = function() {
+ if (!str_format.cache.hasOwnProperty(arguments[0])) {
+ str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
+ }
+ return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
+ };
+
+ str_format.format = function(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
+ for (i = 0; i < tree_length; i++) {
+ node_type = get_type(parse_tree[i]);
+ if (node_type === 'string') {
+ output.push(parse_tree[i]);
+ }
+ else if (node_type === 'array') {
+ match = parse_tree[i]; // convenience purposes only
+ if (match[2]) { // keyword argument
+ arg = argv[cursor];
+ for (k = 0; k < match[2].length; k++) {
+ if (!arg.hasOwnProperty(match[2][k])) {
+ throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
+ }
+ arg = arg[match[2][k]];
+ }
+ }
+ else if (match[1]) { // positional argument (explicit)
+ arg = argv[match[1]];
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++];
+ }
+
+ if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
+ throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
+ }
+
+ // Jed EDIT
+ if ( typeof arg == 'undefined' || arg === null ) {
+ arg = '';
+ }
+ // Jed EDIT
+
+ switch (match[8]) {
+ case 'b': arg = arg.toString(2); break;
+ case 'c': arg = String.fromCharCode(arg); break;
+ case 'd': arg = parseInt(arg, 10); break;
+ case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
+ case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
+ case 'o': arg = arg.toString(8); break;
+ case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
+ case 'u': arg = Math.abs(arg); break;
+ case 'x': arg = arg.toString(16); break;
+ case 'X': arg = arg.toString(16).toUpperCase(); break;
+ }
+ arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
+ pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
+ pad_length = match[6] - String(arg).length;
+ pad = match[6] ? str_repeat(pad_character, pad_length) : '';
+ output.push(match[5] ? arg + pad : pad + arg);
+ }
+ }
+ return output.join('');
+ };
+
+ str_format.cache = {};
+
+ str_format.parse = function(fmt) {
+ var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
+ while (_fmt) {
+ if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
+ parse_tree.push(match[0]);
+ }
+ else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
+ parse_tree.push('%');
+ }
+ else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1;
+ var field_list = [], replacement_field = match[2], field_match = [];
+ if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
+ if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ }
+ else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ }
+ else {
+ throw('[sprintf] huh?');
+ }
+ }
+ }
+ else {
+ throw('[sprintf] huh?');
+ }
+ match[2] = field_list;
+ }
+ else {
+ arg_names |= 2;
+ }
+ if (arg_names === 3) {
+ throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
+ }
+ parse_tree.push(match);
+ }
+ else {
+ throw('[sprintf] huh?');
+ }
+ _fmt = _fmt.substring(match[0].length);
+ }
+ return parse_tree;
+ };
+
+ return str_format;
+ })();
+
+ var vsprintf = function(fmt, argv) {
+ argv.unshift(fmt);
+ return sprintf.apply(null, argv);
+ };
+
+ Jed.parse_plural = function ( plural_forms, n ) {
+ plural_forms = plural_forms.replace(/n/g, n);
+ return Jed.parse_expression(plural_forms);
+ };
+
+ Jed.sprintf = function ( fmt, args ) {
+ if ( {}.toString.call( args ) == '[object Array]' ) {
+ return vsprintf( fmt, [].slice.call(args) );
+ }
+ return sprintf.apply(this, [].slice.call(arguments) );
+ };
+
+ Jed.prototype.sprintf = function () {
+ return Jed.sprintf.apply(this, arguments);
+ };
+ // END sprintf Implementation
+
+ // Start the Plural forms section
+ // This is a full plural form expression parser. It is used to avoid
+ // running 'eval' or 'new Function' directly against the plural
+ // forms.
+ //
+ // This can be important if you get translations done through a 3rd
+ // party vendor. I encourage you to use this instead, however, I
+ // also will provide a 'precompiler' that you can use at build time
+ // to output valid/safe function representations of the plural form
+ // expressions. This means you can build this code out for the most
+ // part.
+ Jed.PF = {};
+
+ Jed.PF.parse = function ( p ) {
+ var plural_str = Jed.PF.extractPluralExpr( p );
+ return Jed.PF.parser.parse.call(Jed.PF.parser, plural_str);
+ };
+
+ Jed.PF.compile = function ( p ) {
+ // Handle trues and falses as 0 and 1
+ function imply( val ) {
+ return (val === true ? 1 : val ? val : 0);
+ }
+
+ var ast = Jed.PF.parse( p );
+ return function ( n ) {
+ return imply( Jed.PF.interpreter( ast )( n ) );
+ };
+ };
+
+ Jed.PF.interpreter = function ( ast ) {
+ return function ( n ) {
+ switch ( ast.type ) {
+ case 'GROUP':
+ return Jed.PF.interpreter( ast.expr )( n );
+ case 'TERNARY':
+ if ( Jed.PF.interpreter( ast.expr )( n ) ) {
+ return Jed.PF.interpreter( ast.truthy )( n );
+ }
+ return Jed.PF.interpreter( ast.falsey )( n );
+ case 'OR':
+ return Jed.PF.interpreter( ast.left )( n ) || Jed.PF.interpreter( ast.right )( n );
+ case 'AND':
+ return Jed.PF.interpreter( ast.left )( n ) && Jed.PF.interpreter( ast.right )( n );
+ case 'LT':
+ return Jed.PF.interpreter( ast.left )( n ) < Jed.PF.interpreter( ast.right )( n );
+ case 'GT':
+ return Jed.PF.interpreter( ast.left )( n ) > Jed.PF.interpreter( ast.right )( n );
+ case 'LTE':
+ return Jed.PF.interpreter( ast.left )( n ) <= Jed.PF.interpreter( ast.right )( n );
+ case 'GTE':
+ return Jed.PF.interpreter( ast.left )( n ) >= Jed.PF.interpreter( ast.right )( n );
+ case 'EQ':
+ return Jed.PF.interpreter( ast.left )( n ) == Jed.PF.interpreter( ast.right )( n );
+ case 'NEQ':
+ return Jed.PF.interpreter( ast.left )( n ) != Jed.PF.interpreter( ast.right )( n );
+ case 'MOD':
+ return Jed.PF.interpreter( ast.left )( n ) % Jed.PF.interpreter( ast.right )( n );
+ case 'VAR':
+ return n;
+ case 'NUM':
+ return ast.val;
+ default:
+ throw new Error("Invalid Token found.");
+ }
+ };
+ };
+
+ Jed.PF.extractPluralExpr = function ( p ) {
+ // trim first
+ p = p.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+
+ if (! /;\s*$/.test(p)) {
+ p = p.concat(';');
+ }
+
+ var nplurals_re = /nplurals\=(\d+);/,
+ plural_re = /plural\=(.*);/,
+ nplurals_matches = p.match( nplurals_re ),
+ plural_matches;
+
+ // Find the nplurals number
+ if ( nplurals_matches.length > 1 ) {
+ nplurals_matches[1];
+ }
+ else {
+ throw new Error('nplurals not found in plural_forms string: ' + p );
+ }
+
+ // remove that data to get to the formula
+ p = p.replace( nplurals_re, "" );
+ plural_matches = p.match( plural_re );
+
+ if (!( plural_matches && plural_matches.length > 1 ) ) {
+ throw new Error('`plural` expression not found: ' + p);
+ }
+ return plural_matches[ 1 ];
+ };
+
+ /* Jison generated parser */
+ Jed.PF.parser = (function(){
+
+ var parser = {trace: function trace() { },
+ yy: {},
+ symbols_: {"error":2,"expressions":3,"e":4,"EOF":5,"?":6,":":7,"||":8,"&&":9,"<":10,"<=":11,">":12,">=":13,"!=":14,"==":15,"%":16,"(":17,")":18,"n":19,"NUMBER":20,"$accept":0,"$end":1},
+ terminals_: {2:"error",5:"EOF",6:"?",7:":",8:"||",9:"&&",10:"<",11:"<=",12:">",13:">=",14:"!=",15:"==",16:"%",17:"(",18:")",19:"n",20:"NUMBER"},
+ productions_: [0,[3,2],[4,5],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,1],[4,1]],
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
+
+ var $0 = $$.length - 1;
+ switch (yystate) {
+ case 1: return { type : 'GROUP', expr: $$[$0-1] };
+ case 2:this.$ = { type: 'TERNARY', expr: $$[$0-4], truthy : $$[$0-2], falsey: $$[$0] };
+ break;
+ case 3:this.$ = { type: "OR", left: $$[$0-2], right: $$[$0] };
+ break;
+ case 4:this.$ = { type: "AND", left: $$[$0-2], right: $$[$0] };
+ break;
+ case 5:this.$ = { type: 'LT', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 6:this.$ = { type: 'LTE', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 7:this.$ = { type: 'GT', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 8:this.$ = { type: 'GTE', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 9:this.$ = { type: 'NEQ', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 10:this.$ = { type: 'EQ', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 11:this.$ = { type: 'MOD', left: $$[$0-2], right: $$[$0] };
+ break;
+ case 12:this.$ = { type: 'GROUP', expr: $$[$0-1] };
+ break;
+ case 13:this.$ = { type: 'VAR' };
+ break;
+ case 14:this.$ = { type: 'NUM', val: Number(yytext) };
+ break;
+ }
+ },
+ table: [{3:1,4:2,17:[1,3],19:[1,4],20:[1,5]},{1:[3]},{5:[1,6],6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{4:17,17:[1,3],19:[1,4],20:[1,5]},{5:[2,13],6:[2,13],7:[2,13],8:[2,13],9:[2,13],10:[2,13],11:[2,13],12:[2,13],13:[2,13],14:[2,13],15:[2,13],16:[2,13],18:[2,13]},{5:[2,14],6:[2,14],7:[2,14],8:[2,14],9:[2,14],10:[2,14],11:[2,14],12:[2,14],13:[2,14],14:[2,14],15:[2,14],16:[2,14],18:[2,14]},{1:[2,1]},{4:18,17:[1,3],19:[1,4],20:[1,5]},{4:19,17:[1,3],19:[1,4],20:[1,5]},{4:20,17:[1,3],19:[1,4],20:[1,5]},{4:21,17:[1,3],19:[1,4],20:[1,5]},{4:22,17:[1,3],19:[1,4],20:[1,5]},{4:23,17:[1,3],19:[1,4],20:[1,5]},{4:24,17:[1,3],19:[1,4],20:[1,5]},{4:25,17:[1,3],19:[1,4],20:[1,5]},{4:26,17:[1,3],19:[1,4],20:[1,5]},{4:27,17:[1,3],19:[1,4],20:[1,5]},{6:[1,7],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[1,28]},{6:[1,7],7:[1,29],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16]},{5:[2,3],6:[2,3],7:[2,3],8:[2,3],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,3]},{5:[2,4],6:[2,4],7:[2,4],8:[2,4],9:[2,4],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,4]},{5:[2,5],6:[2,5],7:[2,5],8:[2,5],9:[2,5],10:[2,5],11:[2,5],12:[2,5],13:[2,5],14:[2,5],15:[2,5],16:[1,16],18:[2,5]},{5:[2,6],6:[2,6],7:[2,6],8:[2,6],9:[2,6],10:[2,6],11:[2,6],12:[2,6],13:[2,6],14:[2,6],15:[2,6],16:[1,16],18:[2,6]},{5:[2,7],6:[2,7],7:[2,7],8:[2,7],9:[2,7],10:[2,7],11:[2,7],12:[2,7],13:[2,7],14:[2,7],15:[2,7],16:[1,16],18:[2,7]},{5:[2,8],6:[2,8],7:[2,8],8:[2,8],9:[2,8],10:[2,8],11:[2,8],12:[2,8],13:[2,8],14:[2,8],15:[2,8],16:[1,16],18:[2,8]},{5:[2,9],6:[2,9],7:[2,9],8:[2,9],9:[2,9],10:[2,9],11:[2,9],12:[2,9],13:[2,9],14:[2,9],15:[2,9],16:[1,16],18:[2,9]},{5:[2,10],6:[2,10],7:[2,10],8:[2,10],9:[2,10],10:[2,10],11:[2,10],12:[2,10],13:[2,10],14:[2,10],15:[2,10],16:[1,16],18:[2,10]},{5:[2,11],6:[2,11],7:[2,11],8:[2,11],9:[2,11],10:[2,11],11:[2,11],12:[2,11],13:[2,11],14:[2,11],15:[2,11],16:[2,11],18:[2,11]},{5:[2,12],6:[2,12],7:[2,12],8:[2,12],9:[2,12],10:[2,12],11:[2,12],12:[2,12],13:[2,12],14:[2,12],15:[2,12],16:[2,12],18:[2,12]},{4:30,17:[1,3],19:[1,4],20:[1,5]},{5:[2,2],6:[1,7],7:[2,2],8:[1,8],9:[1,9],10:[1,10],11:[1,11],12:[1,12],13:[1,13],14:[1,14],15:[1,15],16:[1,16],18:[2,2]}],
+ defaultActions: {6:[2,1]},
+ parseError: function parseError(str, hash) {
+ throw new Error(str);
+ },
+ parse: function parse(input) {
+ var self = this,
+ stack = [0],
+ vstack = [null], // semantic value stack
+ lstack = [], // location stack
+ table = this.table,
+ yytext = '',
+ yylineno = 0,
+ yyleng = 0,
+ recovering = 0,
+ TERROR = 2,
+ EOF = 1;
+
+ //this.reductionCount = this.shiftCount = 0;
+
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ if (typeof this.lexer.yylloc == 'undefined')
+ this.lexer.yylloc = {};
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+
+ if (typeof this.yy.parseError === 'function')
+ this.parseError = this.yy.parseError;
+
+ function popStack (n) {
+ stack.length = stack.length - 2*n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+
+ function lex() {
+ var token;
+ token = self.lexer.lex() || 1; // $end = 1
+ // if token isn't its numeric value, convert
+ if (typeof token !== 'number') {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ }
+
+ var symbol, preErrorSymbol, state, action, r, yyval={},p,len,newState, expected;
+ while (true) {
+ // retreive state number from top of stack
+ state = stack[stack.length-1];
+
+ // use default actions if available
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol == null)
+ symbol = lex();
+ // read action for current state and first input
+ action = table[state] && table[state][symbol];
+ }
+
+ // handle parse error
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
+
+ if (!recovering) {
+ // Report error
+ expected = [];
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
+ expected.push("'"+this.terminals_[p]+"'");
+ }
+ var errStr = '';
+ if (this.lexer.showPosition) {
+ errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
+ } else {
+ errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
+ (symbol == 1 /*EOF*/ ? "end of input" :
+ ("'"+(this.terminals_[symbol] || symbol)+"'"));
+ }
+ this.parseError(errStr,
+ {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+ }
+
+ // just recovered from another error
+ if (recovering == 3) {
+ if (symbol == EOF) {
+ throw new Error(errStr || 'Parsing halted.');
+ }
+
+ // discard current lookahead and grab another
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ symbol = lex();
+ }
+
+ // try to recover from error
+ while (1) {
+ // check for error recovery rule in this state
+ if ((TERROR.toString()) in table[state]) {
+ break;
+ }
+ if (state == 0) {
+ throw new Error(errStr || 'Parsing halted.');
+ }
+ popStack(1);
+ state = stack[stack.length-1];
+ }
+
+ preErrorSymbol = symbol; // save the lookahead token
+ symbol = TERROR; // insert generic error symbol as new lookahead
+ state = stack[stack.length-1];
+ action = table[state] && table[state][TERROR];
+ recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
+ }
+
+ // this shouldn't happen, unless resolve defaults are off
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
+ }
+
+ switch (action[0]) {
+
+ case 1: // shift
+ //this.shiftCount++;
+
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]); // push state
+ symbol = null;
+ if (!preErrorSymbol) { // normal execution/no error
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0)
+ recovering--;
+ } else { // error just occurred, resume old lookahead f/ before error
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+
+ case 2: // reduce
+ //this.reductionCount++;
+
+ len = this.productions_[action[1]][1];
+
+ // perform semantic action
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
+ // default location, uses first token for firsts, last for lasts
+ yyval._$ = {
+ first_line: lstack[lstack.length-(len||1)].first_line,
+ last_line: lstack[lstack.length-1].last_line,
+ first_column: lstack[lstack.length-(len||1)].first_column,
+ last_column: lstack[lstack.length-1].last_column
+ };
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+
+ if (typeof r !== 'undefined') {
+ return r;
+ }
+
+ // pop off stack
+ if (len) {
+ stack = stack.slice(0,-1*len*2);
+ vstack = vstack.slice(0, -1*len);
+ lstack = lstack.slice(0, -1*len);
+ }
+
+ stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ // goto new state = table[STATE][NONTERMINAL]
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
+ stack.push(newState);
+ break;
+
+ case 3: // accept
+ return true;
+ }
+
+ }
+
+ return true;
+ }};/* Jison generated lexer */
+ var lexer = (function(){
+
+ var lexer = ({EOF:1,
+ parseError:function parseError(str, hash) {
+ if (this.yy.parseError) {
+ this.yy.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+ setInput:function (input) {
+ this._input = input;
+ this._more = this._less = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
+ return this;
+ },
+ input:function () {
+ var ch = this._input[0];
+ this.yytext+=ch;
+ this.yyleng++;
+ this.match+=ch;
+ this.matched+=ch;
+ var lines = ch.match(/\n/);
+ if (lines) this.yylineno++;
+ this._input = this._input.slice(1);
+ return ch;
+ },
+ unput:function (ch) {
+ this._input = ch + this._input;
+ return this;
+ },
+ more:function () {
+ this._more = true;
+ return this;
+ },
+ pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+ upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
+ },
+ showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c+"^";
+ },
+ next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) this.done = true;
+
+ var token,
+ match,
+ lines;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i=0;i < rules.length; i++) {
+ match = this._input.match(this.rules[rules[i]]);
+ if (match) {
+ lines = match[0].match(/\n.*/g);
+ if (lines) this.yylineno += lines.length;
+ this.yylloc = {first_line: this.yylloc.last_line,
+ last_line: this.yylineno+1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length};
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ this._more = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
+ if (token) return token;
+ else return;
+ }
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
+ {text: "", token: null, line: this.yylineno});
+ }
+ },
+ lex:function lex() {
+ var r = this.next();
+ if (typeof r !== 'undefined') {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+ begin:function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+ popState:function popState() {
+ return this.conditionStack.pop();
+ },
+ _currentRules:function _currentRules() {
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
+ },
+ topState:function () {
+ return this.conditionStack[this.conditionStack.length-2];
+ },
+ pushState:function begin(condition) {
+ this.begin(condition);
+ }});
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+ switch($avoiding_name_collisions) {
+ case 0:/* skip whitespace */
+ break;
+ case 1:return 20
+ case 2:return 19
+ case 3:return 8
+ case 4:return 9
+ case 5:return 6
+ case 6:return 7
+ case 7:return 11
+ case 8:return 13
+ case 9:return 10
+ case 10:return 12
+ case 11:return 14
+ case 12:return 15
+ case 13:return 16
+ case 14:return 17
+ case 15:return 18
+ case 16:return 5
+ case 17:return 'INVALID'
+ }
+ };
+ lexer.rules = [/^\s+/,/^[0-9]+(\.[0-9]+)?\b/,/^n\b/,/^\|\|/,/^&&/,/^\?/,/^:/,/^<=/,/^>=/,/^</,/^>/,/^!=/,/^==/,/^%/,/^\(/,/^\)/,/^$/,/^./];
+ lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"inclusive":true}};return lexer;})();
+ parser.lexer = lexer;
+ return parser;
+ })();
+ // End parser
+
+ // Handle node, amd, and global systems
+ {
+ if (module.exports) {
+ exports = module.exports = Jed;
+ }
+ exports.Jed = Jed;
+ }
+
+ })();
+} (jed, jed.exports));
+
+// @ts-ignore: no type decl for this library
+new Logger("i18n/index.ts");
+
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Functional programming utilities.
+ */
+var fnutil;
+(function (fnutil) {
+ function all(arr, f) {
+ for (const x of arr) {
+ if (!f(x)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ fnutil.all = all;
+ function any(arr, f) {
+ for (const x of arr) {
+ if (f(x)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ fnutil.any = any;
+})(fnutil || (fnutil = {}));
+
+/**
+ * Hypertext Transfer Protocol (HTTP) response status codes.
+ *
+ * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
+ */
+var HttpStatusCode;
+(function (HttpStatusCode) {
+ /**
+ * The server has received the request headers and the client should proceed to send the request body
+ * (in the case of a request for which a body needs to be sent; for example, a POST request).
+ * Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
+ * To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
+ * and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
+ */
+ HttpStatusCode[HttpStatusCode["Continue"] = 100] = "Continue";
+ /**
+ * The requester has asked the server to switch protocols and the server has agreed to do so.
+ */
+ HttpStatusCode[HttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
+ /**
+ * A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
+ * This code indicates that the server has received and is processing the request, but no response is available yet.
+ * This prevents the client from timing out and assuming the request was lost.
+ */
+ HttpStatusCode[HttpStatusCode["Processing"] = 102] = "Processing";
+ /**
+ * Standard response for successful HTTP requests.
+ * The actual response will depend on the request method used.
+ * In a GET request, the response will contain an entity corresponding to the requested resource.
+ * In a POST request, the response will contain an entity describing or containing the result of the action.
+ */
+ HttpStatusCode[HttpStatusCode["Ok"] = 200] = "Ok";
+ /**
+ * The request has been fulfilled, resulting in the creation of a new resource.
+ */
+ HttpStatusCode[HttpStatusCode["Created"] = 201] = "Created";
+ /**
+ * The request has been accepted for processing, but the processing has not been completed.
+ * The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
+ */
+ HttpStatusCode[HttpStatusCode["Accepted"] = 202] = "Accepted";
+ /**
+ * SINCE HTTP/1.1
+ * The server is a transforming proxy that received a 200 OK from its origin,
+ * but is returning a modified version of the origin's response.
+ */
+ HttpStatusCode[HttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
+ /**
+ * The server successfully processed the request and is not returning any content.
+ */
+ HttpStatusCode[HttpStatusCode["NoContent"] = 204] = "NoContent";
+ /**
+ * The server successfully processed the request, but is not returning any content.
+ * Unlike a 204 response, this response requires that the requester reset the document view.
+ */
+ HttpStatusCode[HttpStatusCode["ResetContent"] = 205] = "ResetContent";
+ /**
+ * The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
+ * The range header is used by HTTP clients to enable resuming of interrupted downloads,
+ * or split a download into multiple simultaneous streams.
+ */
+ HttpStatusCode[HttpStatusCode["PartialContent"] = 206] = "PartialContent";
+ /**
+ * The message body that follows is an XML message and can contain a number of separate response codes,
+ * depending on how many sub-requests were made.
+ */
+ HttpStatusCode[HttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
+ /**
+ * The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
+ * and are not being included again.
+ */
+ HttpStatusCode[HttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
+ /**
+ * The server has fulfilled a request for the resource,
+ * and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
+ */
+ HttpStatusCode[HttpStatusCode["ImUsed"] = 226] = "ImUsed";
+ /**
+ * Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
+ * For example, this code could be used to present multiple video format options,
+ * to list files with different filename extensions, or to suggest word-sense disambiguation.
+ */
+ HttpStatusCode[HttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
+ /**
+ * This and all future requests should be directed to the given URI.
+ */
+ HttpStatusCode[HttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
+ /**
+ * This is an example of industry practice contradicting the standard.
+ * The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
+ * (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
+ * with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
+ * to distinguish between the two behaviours. However, some Web applications and frameworks
+ * use the 302 status code as if it were the 303.
+ */
+ HttpStatusCode[HttpStatusCode["Found"] = 302] = "Found";
+ /**
+ * SINCE HTTP/1.1
+ * The response to the request can be found under another URI using a GET method.
+ * When received in response to a POST (or PUT/DELETE), the client should presume that
+ * the server has received the data and should issue a redirect with a separate GET message.
+ */
+ HttpStatusCode[HttpStatusCode["SeeOther"] = 303] = "SeeOther";
+ /**
+ * Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
+ * In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
+ */
+ HttpStatusCode[HttpStatusCode["NotModified"] = 304] = "NotModified";
+ /**
+ * SINCE HTTP/1.1
+ * The requested resource is available only through a proxy, the address for which is provided in the response.
+ * Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
+ */
+ HttpStatusCode[HttpStatusCode["UseProxy"] = 305] = "UseProxy";
+ /**
+ * No longer used. Originally meant "Subsequent requests should use the specified proxy."
+ */
+ HttpStatusCode[HttpStatusCode["SwitchProxy"] = 306] = "SwitchProxy";
+ /**
+ * SINCE HTTP/1.1
+ * In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
+ * In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
+ * For example, a POST request should be repeated using another POST request.
+ */
+ HttpStatusCode[HttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
+ /**
+ * The request and all future requests should be repeated using another URI.
+ * 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
+ * So, for example, submitting a form to a permanently redirected resource may continue smoothly.
+ */
+ HttpStatusCode[HttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
+ /**
+ * The server cannot or will not process the request due to an apparent client error
+ * (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
+ */
+ HttpStatusCode[HttpStatusCode["BadRequest"] = 400] = "BadRequest";
+ /**
+ * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
+ * been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
+ * requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
+ * "unauthenticated",i.e. the user does not have the necessary credentials.
+ */
+ HttpStatusCode[HttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
+ /**
+ * Reserved for future use. The original intention was that this code might be used as part of some form of digital
+ * cash or micro payment scheme, but that has not happened, and this code is not usually used.
+ * Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
+ */
+ HttpStatusCode[HttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
+ /**
+ * The request was valid, but the server is refusing action.
+ * The user might not have the necessary permissions for a resource.
+ */
+ HttpStatusCode[HttpStatusCode["Forbidden"] = 403] = "Forbidden";
+ /**
+ * The requested resource could not be found but may be available in the future.
+ * Subsequent requests by the client are permissible.
+ */
+ HttpStatusCode[HttpStatusCode["NotFound"] = 404] = "NotFound";
+ /**
+ * A request method is not supported for the requested resource;
+ * for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
+ */
+ HttpStatusCode[HttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
+ /**
+ * The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
+ */
+ HttpStatusCode[HttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
+ /**
+ * The client must first authenticate itself with the proxy.
+ */
+ HttpStatusCode[HttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
+ /**
+ * The server timed out waiting for the request.
+ * According to HTTP specifications:
+ * "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
+ */
+ HttpStatusCode[HttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
+ /**
+ * Indicates that the request could not be processed because of conflict in the request,
+ * such as an edit conflict between multiple simultaneous updates.
+ */
+ HttpStatusCode[HttpStatusCode["Conflict"] = 409] = "Conflict";
+ /**
+ * Indicates that the resource requested is no longer available and will not be available again.
+ * This should be used when a resource has been intentionally removed and the resource should be purged.
+ * Upon receiving a 410 status code, the client should not request the resource in the future.
+ * Clients such as search engines should remove the resource from their indices.
+ * Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
+ */
+ HttpStatusCode[HttpStatusCode["Gone"] = 410] = "Gone";
+ /**
+ * The request did not specify the length of its content, which is required by the requested resource.
+ */
+ HttpStatusCode[HttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
+ /**
+ * The server does not meet one of the preconditions that the requester put on the request.
+ */
+ HttpStatusCode[HttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
+ /**
+ * The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
+ */
+ HttpStatusCode[HttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
+ /**
+ * The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
+ * in which case it should be converted to a POST request.
+ * Called "Request-URI Too Long" previously.
+ */
+ HttpStatusCode[HttpStatusCode["UriTooLong"] = 414] = "UriTooLong";
+ /**
+ * The request entity has a media type which the server or resource does not support.
+ * For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
+ */
+ HttpStatusCode[HttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
+ /**
+ * The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
+ * For example, if the client asked for a part of the file that lies beyond the end of the file.
+ * Called "Requested Range Not Satisfiable" previously.
+ */
+ HttpStatusCode[HttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
+ /**
+ * The server cannot meet the requirements of the Expect request-header field.
+ */
+ HttpStatusCode[HttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
+ /**
+ * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
+ * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
+ * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
+ */
+ HttpStatusCode[HttpStatusCode["IAmATeapot"] = 418] = "IAmATeapot";
+ /**
+ * The request was directed at a server that is not able to produce a response (for example because a connection reuse).
+ */
+ HttpStatusCode[HttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
+ /**
+ * The request was well-formed but was unable to be followed due to semantic errors.
+ */
+ HttpStatusCode[HttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
+ /**
+ * The resource that is being accessed is locked.
+ */
+ HttpStatusCode[HttpStatusCode["Locked"] = 423] = "Locked";
+ /**
+ * The request failed due to failure of a previous request (e.g., a PROPPATCH).
+ */
+ HttpStatusCode[HttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
+ /**
+ * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
+ */
+ HttpStatusCode[HttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
+ /**
+ * The origin server requires the request to be conditional.
+ * Intended to prevent "the 'lost update' problem, where a client
+ * GETs a resource's state, modifies it, and PUTs it back to the server,
+ * when meanwhile a third party has modified the state on the server, leading to a conflict."
+ */
+ HttpStatusCode[HttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
+ /**
+ * The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
+ */
+ HttpStatusCode[HttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
+ /**
+ * The server is unwilling to process the request because either an individual header field,
+ * or all the header fields collectively, are too large.
+ */
+ HttpStatusCode[HttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
+ /**
+ * A server operator has received a legal demand to deny access to a resource or to a set of resources
+ * that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
+ */
+ HttpStatusCode[HttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
+ /**
+ * A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
+ */
+ HttpStatusCode[HttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
+ /**
+ * The server either does not recognize the request method, or it lacks the ability to fulfill the request.
+ * Usually this implies future availability (e.g., a new feature of a web-service API).
+ */
+ HttpStatusCode[HttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
+ /**
+ * The server was acting as a gateway or proxy and received an invalid response from the upstream server.
+ */
+ HttpStatusCode[HttpStatusCode["BadGateway"] = 502] = "BadGateway";
+ /**
+ * The server is currently unavailable (because it is overloaded or down for maintenance).
+ * Generally, this is a temporary state.
+ */
+ HttpStatusCode[HttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
+ /**
+ * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
+ */
+ HttpStatusCode[HttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
+ /**
+ * The server does not support the HTTP protocol version used in the request
+ */
+ HttpStatusCode[HttpStatusCode["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
+ /**
+ * Transparent content negotiation for the request results in a circular reference.
+ */
+ HttpStatusCode[HttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
+ /**
+ * The server is unable to store the representation needed to complete the request.
+ */
+ HttpStatusCode[HttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
+ /**
+ * The server detected an infinite loop while processing the request.
+ */
+ HttpStatusCode[HttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
+ /**
+ * Further extensions to the request are required for the server to fulfill it.
+ */
+ HttpStatusCode[HttpStatusCode["NotExtended"] = 510] = "NotExtended";
+ /**
+ * The client needs to authenticate to gain network access.
+ * Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
+ * to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
+ */
+ HttpStatusCode[HttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
+})(HttpStatusCode || (HttpStatusCode = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Implementation of token bucket throttling.
+ */
+const logger$v = new Logger("RequestThrottler.ts");
+/**
+ * Maximum request per second, per origin.
+ */
+const MAX_PER_SECOND = 100;
+/**
+ * Maximum request per minute, per origin.
+ */
+const MAX_PER_MINUTE = 500;
+/**
+ * Maximum request per hour, per origin.
+ */
+const MAX_PER_HOUR = 2000;
+/**
+ * Throttling state for one origin.
+ */
+class OriginState {
+ constructor() {
+ this.tokensSecond = MAX_PER_SECOND;
+ this.tokensMinute = MAX_PER_MINUTE;
+ this.tokensHour = MAX_PER_HOUR;
+ this.lastUpdate = AbsoluteTime.now();
+ }
+ refill() {
+ const now = AbsoluteTime.now();
+ if (AbsoluteTime.cmp(now, this.lastUpdate) < 0) {
+ // Did the system time change?
+ this.lastUpdate = now;
+ return;
+ }
+ const d = AbsoluteTime.difference(now, this.lastUpdate);
+ if (d.d_ms === "forever") {
+ throw Error("assertion failed");
+ }
+ this.tokensSecond = Math.min(MAX_PER_SECOND, this.tokensSecond + d.d_ms / 1000);
+ this.tokensMinute = Math.min(MAX_PER_MINUTE, this.tokensMinute + d.d_ms / 1000 / 60);
+ this.tokensHour = Math.min(MAX_PER_HOUR, this.tokensHour + d.d_ms / 1000 / 60 / 60);
+ this.lastUpdate = now;
+ }
+ /**
+ * Return true if the request for this origin should be throttled.
+ * Otherwise, take a token out of the respective buckets.
+ */
+ applyThrottle() {
+ this.refill();
+ if (this.tokensSecond < 1) {
+ logger$v.warn("request throttled (per second limit exceeded)");
+ return true;
+ }
+ if (this.tokensMinute < 1) {
+ logger$v.warn("request throttled (per minute limit exceeded)");
+ return true;
+ }
+ if (this.tokensHour < 1) {
+ logger$v.warn("request throttled (per hour limit exceeded)");
+ return true;
+ }
+ this.tokensSecond--;
+ this.tokensMinute--;
+ this.tokensHour--;
+ return false;
+ }
+}
+/**
+ * Request throttler, used as a "last layer of defense" when some
+ * other part of the re-try logic is broken and we're sending too
+ * many requests to the same exchange/bank/merchant.
+ */
+class RequestThrottler {
+ constructor() {
+ this.perOriginInfo = {};
+ }
+ /**
+ * Get the throttling state for an origin, or
+ * initialize if no state is associated with the
+ * origin yet.
+ */
+ getState(origin) {
+ const s = this.perOriginInfo[origin];
+ if (s) {
+ return s;
+ }
+ const ns = (this.perOriginInfo[origin] = new OriginState());
+ return ns;
+ }
+ /**
+ * Apply throttling to a request.
+ *
+ * @returns whether the request should be throttled.
+ */
+ applyThrottle(requestUrl) {
+ const origin = new URL(requestUrl).origin;
+ return this.getState(origin).applyThrottle();
+ }
+ /**
+ * Get the throttle statistics for a particular URL.
+ */
+ getThrottleStats(requestUrl) {
+ const origin = new URL(requestUrl).origin;
+ const state = this.getState(origin);
+ return {
+ tokensHour: state.tokensHour,
+ tokensMinute: state.tokensMinute,
+ tokensSecond: state.tokensSecond,
+ maxTokensHour: MAX_PER_HOUR,
+ maxTokensMinute: MAX_PER_MINUTE,
+ maxTokensSecond: MAX_PER_SECOND,
+ };
+ }
+}
+
+/*
+MIT License
+
+Copyright (c) 2017 Conrad Reuter
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+const NOOP = () => { };
+/**
+ * A token that can be passed around to inform consumers of the token that a
+ * certain operation has been cancelled.
+ */
+class CancellationToken {
+ constructor(
+ /**
+ * Whether the token is already cancelled.
+ */
+ _isCancelled,
+ /**
+ * Whether the token can be cancelled.
+ */
+ _canBeCancelled) {
+ this._isCancelled = _isCancelled;
+ this._canBeCancelled = _canBeCancelled;
+ this._callbacks = new Set();
+ }
+ /**
+ * Whether the token has been cancelled.
+ */
+ get isCancelled() {
+ return this._isCancelled;
+ }
+ /**
+ * Whether the token can be cancelled.
+ */
+ get canBeCancelled() {
+ return this._canBeCancelled;
+ }
+ /**
+ * Why this token has been cancelled.
+ */
+ get reason() {
+ if (this.isCancelled) {
+ return this._reason;
+ }
+ else {
+ throw new Error("This token is not cancelled.");
+ }
+ }
+ /**
+ * Make a promise that resolves when the async operation resolves,
+ * or rejects when the operation is rejected or this token is cancelled.
+ */
+ racePromise(asyncOperation) {
+ if (!this.canBeCancelled) {
+ return asyncOperation;
+ }
+ return new Promise((resolve, reject) => {
+ // we could use Promise.finally here as soon as it's implemented in the major browsers
+ const unregister = this.onCancelled((reason) => reject(new CancellationToken.CancellationError(reason)));
+ asyncOperation.then((value) => {
+ resolve(value);
+ unregister();
+ }, (err) => {
+ reject(err);
+ unregister();
+ });
+ });
+ }
+ /**
+ * Throw a {CancellationToken.CancellationError} if this token is cancelled.
+ */
+ throwIfCancelled() {
+ if (this._isCancelled) {
+ throw new CancellationToken.CancellationError(this._reason);
+ }
+ }
+ /**
+ * Invoke the callback when this token is cancelled.
+ * If this token is already cancelled, the callback is invoked immediately.
+ * Returns a function that unregisters the cancellation callback.
+ */
+ onCancelled(cb) {
+ var _a;
+ if (!this.canBeCancelled) {
+ return NOOP;
+ }
+ if (this.isCancelled) {
+ cb(this.reason);
+ return NOOP;
+ }
+ /* istanbul ignore next */
+ (_a = this._callbacks) === null || _a === void 0 ? void 0 : _a.add(cb);
+ return () => { var _a; return (_a = this._callbacks) === null || _a === void 0 ? void 0 : _a.delete(cb); };
+ }
+ /**
+ * Create a {CancellationTokenSource}.
+ */
+ static create() {
+ const token = new CancellationToken(false, true);
+ const cancel = (reason) => {
+ var _a;
+ if (token._isCancelled)
+ return;
+ token._isCancelled = true;
+ token._reason = reason;
+ (_a = token._callbacks) === null || _a === void 0 ? void 0 : _a.forEach((cb) => cb(reason));
+ dispose();
+ };
+ const dispose = () => {
+ token._canBeCancelled = token.isCancelled;
+ delete token._callbacks; // release memory
+ };
+ return { token, cancel, dispose };
+ }
+ /**
+ * Create a {CancellationTokenSource}.
+ * The token will be cancelled automatically after the specified timeout in milliseconds.
+ */
+ static timeout(ms) {
+ const { token, cancel: originalCancel, dispose: originalDispose, } = CancellationToken.create();
+ let timer;
+ timer = setTimeout(() => originalCancel(CancellationToken.timeout), ms);
+ const disposeTimer = () => {
+ if (timer == null)
+ return;
+ clearTimeout(timer);
+ timer = null;
+ };
+ const cancel = (reason) => {
+ disposeTimer();
+ originalCancel(reason);
+ };
+ /* istanbul ignore next */
+ const dispose = () => {
+ disposeTimer();
+ originalDispose();
+ };
+ return { token, cancel, dispose };
+ }
+ /**
+ * Create a {CancellationToken} that is cancelled when all of the given tokens are cancelled.
+ *
+ * This is like {Promise<T>.all} for {CancellationToken}s.
+ */
+ static all(...tokens) {
+ // If *any* of the tokens cannot be cancelled, then the token we return can never be.
+ if (tokens.some((token) => !token.canBeCancelled)) {
+ return CancellationToken.CONTINUE;
+ }
+ const combined = CancellationToken.create();
+ let countdown = tokens.length;
+ const handleNextTokenCancelled = () => {
+ if (--countdown === 0) {
+ const reasons = tokens.map((token) => token._reason);
+ combined.cancel(reasons);
+ }
+ };
+ tokens.forEach((token) => token.onCancelled(handleNextTokenCancelled));
+ return combined.token;
+ }
+ /**
+ * Create a {CancellationToken} that is cancelled when at least one of the given tokens is cancelled.
+ *
+ * This is like {Promise<T>.race} for {CancellationToken}s.
+ */
+ static race(...tokens) {
+ // If *any* of the tokens is already cancelled, immediately return that token.
+ for (const token of tokens) {
+ if (token._isCancelled) {
+ return token;
+ }
+ }
+ const combined = CancellationToken.create();
+ let unregistrations;
+ const handleAnyTokenCancelled = (reason) => {
+ unregistrations.forEach((unregister) => unregister()); // release memory
+ combined.cancel(reason);
+ };
+ unregistrations = tokens.map((token) => token.onCancelled(handleAnyTokenCancelled));
+ return combined.token;
+ }
+}
+/**
+ * A cancellation token that is already cancelled.
+ */
+CancellationToken.CANCELLED = new CancellationToken(true, true);
+/**
+ * A cancellation token that is never cancelled.
+ */
+CancellationToken.CONTINUE = new CancellationToken(false, false);
+/* istanbul ignore next */
+(function (CancellationToken) {
+ /**
+ * The error that is thrown when a {CancellationToken} has been cancelled and a
+ * consumer of the token calls {CancellationToken.throwIfCancelled} on it.
+ */
+ class CancellationError extends Error {
+ constructor(
+ /**
+ * The reason why the token was cancelled.
+ */
+ reason) {
+ super("Operation cancelled");
+ this.reason = reason;
+ Object.setPrototypeOf(this, CancellationError.prototype);
+ }
+ }
+ CancellationToken.CancellationError = CancellationError;
+})(CancellationToken || (CancellationToken = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+new Logger("contractTerms.ts");
+var ContractTermsUtil;
+(function (ContractTermsUtil) {
+ function forgetAllImpl(anyJson, path, pred) {
+ const dup = JSON.parse(JSON.stringify(anyJson));
+ if (Array.isArray(dup)) {
+ for (let i = 0; i < dup.length; i++) {
+ dup[i] = forgetAllImpl(dup[i], [...path, `${i}`], pred);
+ }
+ }
+ else if (typeof dup === "object" && dup != null) {
+ if (typeof dup.$forgettable === "object") {
+ for (const x of Object.keys(dup.$forgettable)) {
+ if (!pred([...path, x])) {
+ continue;
+ }
+ if (!dup.$forgotten) {
+ dup.$forgotten = {};
+ }
+ if (!dup.$forgotten[x]) {
+ const membValCanon = stringToBytes(canonicalJson(scrub(dup[x])) + "\0");
+ const membSalt = stringToBytes(dup.$forgettable[x] + "\0");
+ const h = kdf(64, membValCanon, membSalt, new Uint8Array([]));
+ dup.$forgotten[x] = encodeCrock(h);
+ }
+ delete dup[x];
+ delete dup.$forgettable[x];
+ }
+ if (Object.keys(dup.$forgettable).length === 0) {
+ delete dup.$forgettable;
+ }
+ }
+ for (const x of Object.keys(dup)) {
+ if (x.startsWith("$")) {
+ continue;
+ }
+ dup[x] = forgetAllImpl(dup[x], [...path, x], pred);
+ }
+ }
+ return dup;
+ }
+ ContractTermsUtil.forgetAllImpl = forgetAllImpl;
+ /**
+ * Scrub all forgettable members from an object.
+ */
+ function scrub(anyJson) {
+ return forgetAllImpl(anyJson, [], () => true);
+ }
+ ContractTermsUtil.scrub = scrub;
+ /**
+ * Recursively forget all forgettable members of an object,
+ * where the path matches a predicate.
+ */
+ function forgetAll(anyJson, pred) {
+ return forgetAllImpl(anyJson, [], pred);
+ }
+ ContractTermsUtil.forgetAll = forgetAll;
+ /**
+ * Generate a salt for all members marked as forgettable,
+ * but which don't have an actual salt yet.
+ */
+ function saltForgettable(anyJson) {
+ const dup = JSON.parse(JSON.stringify(anyJson));
+ if (Array.isArray(dup)) {
+ for (let i = 0; i < dup.length; i++) {
+ dup[i] = saltForgettable(dup[i]);
+ }
+ }
+ else if (typeof dup === "object" && dup !== null) {
+ if (typeof dup.$forgettable === "object") {
+ for (const k of Object.keys(dup.$forgettable)) {
+ if (dup.$forgettable[k] === true) {
+ dup.$forgettable[k] = encodeCrock(getRandomBytes(32));
+ }
+ }
+ }
+ for (const x of Object.keys(dup)) {
+ if (x.startsWith("$")) {
+ continue;
+ }
+ dup[x] = saltForgettable(dup[x]);
+ }
+ }
+ return dup;
+ }
+ ContractTermsUtil.saltForgettable = saltForgettable;
+ const nameRegex = /^[0-9A-Za-z_]+$/;
+ /**
+ * Check that the given JSON object is well-formed with regards
+ * to forgettable fields and other restrictions for forgettable JSON.
+ */
+ function validateForgettable(anyJson) {
+ var _a;
+ if (typeof anyJson === "string") {
+ return true;
+ }
+ if (typeof anyJson === "number") {
+ return (Number.isInteger(anyJson) &&
+ anyJson >= Number.MIN_SAFE_INTEGER &&
+ anyJson <= Number.MAX_SAFE_INTEGER);
+ }
+ if (typeof anyJson === "boolean") {
+ return true;
+ }
+ if (anyJson === null) {
+ return true;
+ }
+ if (Array.isArray(anyJson)) {
+ return anyJson.every((x) => validateForgettable(x));
+ }
+ if (typeof anyJson === "object") {
+ for (const k of Object.keys(anyJson)) {
+ if (k.match(nameRegex)) {
+ if (validateForgettable(anyJson[k])) {
+ continue;
+ }
+ else {
+ return false;
+ }
+ }
+ if (k === "$forgettable") {
+ const fga = anyJson.$forgettable;
+ if (!fga || typeof fga !== "object") {
+ return false;
+ }
+ for (const fk of Object.keys(fga)) {
+ if (!fk.match(nameRegex)) {
+ return false;
+ }
+ if (!(fk in anyJson)) {
+ return false;
+ }
+ const fv = anyJson.$forgettable[fk];
+ if (typeof fv !== "string") {
+ return false;
+ }
+ }
+ }
+ else if (k === "$forgotten") {
+ const fgo = anyJson.$forgotten;
+ if (!fgo || typeof fgo !== "object") {
+ return false;
+ }
+ for (const fk of Object.keys(fgo)) {
+ if (!fk.match(nameRegex)) {
+ return false;
+ }
+ // Check that the value has actually been forgotten.
+ if (fk in anyJson) {
+ return false;
+ }
+ const fv = anyJson.$forgotten[fk];
+ if (typeof fv !== "string") {
+ return false;
+ }
+ try {
+ const decFv = decodeCrock(fv);
+ if (decFv.length != 64) {
+ return false;
+ }
+ }
+ catch (e) {
+ return false;
+ }
+ // Check that salt has been deleted after forgetting.
+ if (((_a = anyJson.$forgettable) === null || _a === void 0 ? void 0 : _a[k]) !== undefined) {
+ return false;
+ }
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+ ContractTermsUtil.validateForgettable = validateForgettable;
+ /**
+ * Check that no forgettable information has been forgotten.
+ *
+ * Must only be called on an object already validated with validateForgettable.
+ */
+ function validateNothingForgotten(contractTerms) {
+ throw Error("not implemented yet");
+ }
+ ContractTermsUtil.validateNothingForgotten = validateNothingForgotten;
+ /**
+ * Hash a contract terms object. Forgettable fields
+ * are scrubbed and JSON canonicalization is applied
+ * before hashing.
+ */
+ function hashContractTerms(contractTerms) {
+ const cleaned = scrub(contractTerms);
+ const canon = canonicalJson(cleaned) + "\0";
+ const bytes = stringToBytes(canon);
+ return encodeCrock(hash(bytes));
+ }
+ ContractTermsUtil.hashContractTerms = hashContractTerms;
+})(ContractTermsUtil || (ContractTermsUtil = {}));
+
+/*
+Original work Copyright (c) Isaac Z. Schlueter and Contributors
+Modified work Copyright (c) 2021 Taler Systems S.A.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+*/
+let path = { sep: "/" };
+try {
+ path.sep = require("path").sep;
+}
+catch (er) { }
+// characters that need to be escaped in RegExp.
+charSet("().*{}+?[]^$\\!");
+// "abc" -> { a:true, b:true, c:true }
+function charSet(s) {
+ return s.split("").reduce(function (set, c) {
+ set[c] = true;
+ return set;
+ }, {});
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+var clk;
+(function (clk) {
+ class Converter {
+ }
+ clk.INT = new Converter();
+ clk.STRING = new Converter();
+ function splitOpt(opt) {
+ const idx = opt.indexOf("=");
+ if (idx == -1) {
+ return { key: opt };
+ }
+ return { key: opt.substring(0, idx), value: opt.substring(idx + 1) };
+ }
+ function formatListing(key, value) {
+ const res = " " + key;
+ if (!value) {
+ return res;
+ }
+ if (res.length >= 25) {
+ return res + "\n" + " " + value;
+ }
+ else {
+ return res.padEnd(24) + " " + value;
+ }
+ }
+ class CommandGroup {
+ constructor(argKey, name, scArgs) {
+ this.argKey = argKey;
+ this.name = name;
+ this.scArgs = scArgs;
+ this.shortOptions = {};
+ this.longOptions = {};
+ this.subcommandMap = {};
+ this.subcommands = [];
+ this.options = [];
+ this.arguments = [];
+ }
+ action(f) {
+ if (this.myAction) {
+ throw Error("only one action supported per command");
+ }
+ this.myAction = f;
+ }
+ requiredOption(name, flagspec, conv, args = {}) {
+ const def = {
+ args: args,
+ conv: conv,
+ flagspec: flagspec,
+ isFlag: false,
+ required: true,
+ name: name,
+ };
+ this.options.push(def);
+ for (const flag of flagspec) {
+ if (flag.startsWith("--")) {
+ const flagname = flag.substring(2);
+ this.longOptions[flagname] = def;
+ }
+ else if (flag.startsWith("-")) {
+ const flagname = flag.substring(1);
+ this.shortOptions[flagname] = def;
+ }
+ else {
+ throw Error("option must start with '-' or '--'");
+ }
+ }
+ return this;
+ }
+ maybeOption(name, flagspec, conv, args = {}) {
+ const def = {
+ args: args,
+ conv: conv,
+ flagspec: flagspec,
+ isFlag: false,
+ required: false,
+ name: name,
+ };
+ this.options.push(def);
+ for (const flag of flagspec) {
+ if (flag.startsWith("--")) {
+ const flagname = flag.substring(2);
+ this.longOptions[flagname] = def;
+ }
+ else if (flag.startsWith("-")) {
+ const flagname = flag.substring(1);
+ this.shortOptions[flagname] = def;
+ }
+ else {
+ throw Error("option must start with '-' or '--'");
+ }
+ }
+ return this;
+ }
+ requiredArgument(name, conv, args = {}) {
+ const argDef = {
+ args: args,
+ conv: conv,
+ name: name,
+ required: true,
+ };
+ this.arguments.push(argDef);
+ return this;
+ }
+ maybeArgument(name, conv, args = {}) {
+ const argDef = {
+ args: args,
+ conv: conv,
+ name: name,
+ required: false,
+ };
+ this.arguments.push(argDef);
+ return this;
+ }
+ flag(name, flagspec, args = {}) {
+ const def = {
+ args: args,
+ flagspec: flagspec,
+ isFlag: true,
+ required: false,
+ name: name,
+ };
+ this.options.push(def);
+ for (const flag of flagspec) {
+ if (flag.startsWith("--")) {
+ const flagname = flag.substring(2);
+ this.longOptions[flagname] = def;
+ }
+ else if (flag.startsWith("-")) {
+ const flagname = flag.substring(1);
+ this.shortOptions[flagname] = def;
+ }
+ else {
+ throw Error("option must start with '-' or '--'");
+ }
+ }
+ return this;
+ }
+ subcommand(argKey, name, args = {}) {
+ const cg = new CommandGroup(argKey, name, args);
+ const def = {
+ commandGroup: cg,
+ name: name,
+ args: args,
+ };
+ cg.flag("help", ["-h", "--help"], {
+ help: "Show this message and exit.",
+ });
+ this.subcommandMap[name] = def;
+ this.subcommands.push(def);
+ this.subcommands = this.subcommands.sort((x1, x2) => {
+ const a = x1.name;
+ const b = x2.name;
+ if (a === b) {
+ return 0;
+ }
+ else if (a < b) {
+ return -1;
+ }
+ else {
+ return 1;
+ }
+ });
+ return cg;
+ }
+ printHelp(progName, parents) {
+ var _a, _b, _c;
+ let usageSpec = "";
+ for (const p of parents) {
+ usageSpec += ((_a = p.name) !== null && _a !== void 0 ? _a : progName) + " ";
+ if (p.arguments.length >= 1) {
+ usageSpec += "<ARGS...> ";
+ }
+ }
+ usageSpec += ((_b = this.name) !== null && _b !== void 0 ? _b : progName) + " ";
+ if (this.subcommands.length != 0) {
+ usageSpec += "COMMAND ";
+ }
+ for (const a of this.arguments) {
+ const argName = (_c = a.args.metavar) !== null && _c !== void 0 ? _c : a.name;
+ usageSpec += `<${argName}> `;
+ }
+ usageSpec = usageSpec.trimRight();
+ console.log(`Usage: ${usageSpec}`);
+ if (this.scArgs.help) {
+ console.log();
+ console.log(this.scArgs.help);
+ }
+ if (this.options.length != 0) {
+ console.log();
+ console.log("Options:");
+ for (const opt of this.options) {
+ let optSpec = opt.flagspec.join(", ");
+ if (!opt.isFlag) {
+ optSpec = optSpec + "=VALUE";
+ }
+ console.log(formatListing(optSpec, opt.args.help));
+ }
+ }
+ if (this.subcommands.length != 0) {
+ console.log();
+ console.log("Commands:");
+ for (const subcmd of this.subcommands) {
+ console.log(formatListing(subcmd.name, subcmd.args.help));
+ }
+ }
+ }
+ /**
+ * Run the (sub-)command with the given command line parameters.
+ */
+ run(progname, parents, unparsedArgs, parsedArgs) {
+ var _a;
+ let posArgIndex = 0;
+ let argsTerminated = false;
+ let i;
+ let foundSubcommand = undefined;
+ const myArgs = (parsedArgs[this.argKey] = {});
+ const foundOptions = {};
+ const currentName = (_a = this.name) !== null && _a !== void 0 ? _a : progname;
+ const storeOption = (def, value) => {
+ foundOptions[def.name] = true;
+ if (def.conv === clk.INT) {
+ myArgs[def.name] = Number.parseInt(value);
+ }
+ else if (def.conv == null || def.conv === clk.STRING) {
+ myArgs[def.name] = value;
+ }
+ else {
+ throw Error("unknown converter");
+ }
+ };
+ const storeFlag = (def, value) => {
+ foundOptions[def.name] = true;
+ myArgs[def.name] = value;
+ };
+ for (i = 0; i < unparsedArgs.length; i++) {
+ const argVal = unparsedArgs[i];
+ if (argsTerminated == false) {
+ if (argVal === "--") {
+ argsTerminated = true;
+ continue;
+ }
+ if (argVal.startsWith("--")) {
+ const opt = argVal.substring(2);
+ const r = splitOpt(opt);
+ const d = this.longOptions[r.key];
+ if (!d) {
+ console.error(`error: unknown option '--${r.key}' for ${currentName}`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ if (d.isFlag) {
+ if (r.value !== undefined) {
+ console.error(`error: flag '--${r.key}' does not take a value`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ storeFlag(d, true);
+ }
+ else {
+ if (r.value === undefined) {
+ if (i === unparsedArgs.length - 1) {
+ console.error(`error: option '--${r.key}' needs an argument`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ storeOption(d, unparsedArgs[i + 1]);
+ i++;
+ }
+ else {
+ storeOption(d, r.value);
+ }
+ }
+ continue;
+ }
+ if (argVal.startsWith("-") && argVal != "-") {
+ const optShort = argVal.substring(1);
+ for (let si = 0; si < optShort.length; si++) {
+ const chr = optShort[si];
+ const opt = this.shortOptions[chr];
+ if (!opt) {
+ console.error(`error: option '-${chr}' not known`);
+ process__default["default"].exit(-1);
+ }
+ if (opt.isFlag) {
+ storeFlag(opt, true);
+ }
+ else {
+ if (si == optShort.length - 1) {
+ if (i === unparsedArgs.length - 1) {
+ console.error(`error: option '-${chr}' needs an argument`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ else {
+ storeOption(opt, unparsedArgs[i + 1]);
+ i++;
+ }
+ }
+ else {
+ storeOption(opt, optShort.substring(si + 1));
+ }
+ break;
+ }
+ }
+ continue;
+ }
+ }
+ if (this.subcommands.length != 0) {
+ const subcmd = this.subcommandMap[argVal];
+ if (!subcmd) {
+ console.error(`error: unknown command '${argVal}'`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ foundSubcommand = subcmd.commandGroup;
+ break;
+ }
+ else {
+ const d = this.arguments[posArgIndex];
+ if (!d) {
+ console.error(`error: too many arguments for ${currentName}`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ myArgs[d.name] = unparsedArgs[i];
+ posArgIndex++;
+ }
+ }
+ if (parsedArgs[this.argKey].help) {
+ this.printHelp(progname, parents);
+ process__default["default"].exit(0);
+ throw Error("not reached");
+ }
+ for (let i = posArgIndex; i < this.arguments.length; i++) {
+ const d = this.arguments[i];
+ if (d.required) {
+ if (d.args.default !== undefined) {
+ myArgs[d.name] = d.args.default;
+ }
+ else {
+ console.error(`error: missing positional argument '${d.name}' for ${currentName}`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ }
+ }
+ for (const option of this.options) {
+ if (option.isFlag == false && option.required == true) {
+ if (!foundOptions[option.name]) {
+ if (option.args.default !== undefined) {
+ myArgs[option.name] = option.args.default;
+ }
+ else {
+ const name = option.flagspec.join(",");
+ console.error(`error: missing option '${name}'`);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ }
+ }
+ }
+ for (const option of this.options) {
+ const ph = option.args.onPresentHandler;
+ if (ph && foundOptions[option.name]) {
+ ph(myArgs[option.name]);
+ }
+ }
+ if (foundSubcommand) {
+ foundSubcommand.run(progname, Array.prototype.concat(parents, [this]), unparsedArgs.slice(i + 1), parsedArgs);
+ }
+ else if (this.myAction) {
+ let r;
+ try {
+ r = this.myAction(parsedArgs);
+ }
+ catch (e) {
+ console.error(`An error occurred while running ${currentName}`);
+ console.error(e);
+ process__default["default"].exit(1);
+ }
+ Promise.resolve(r).catch((e) => {
+ console.error(`An error occurred while running ${currentName}`);
+ console.error(e);
+ process__default["default"].exit(1);
+ });
+ }
+ else {
+ this.printHelp(progname, parents);
+ process__default["default"].exit(-1);
+ throw Error("not reached");
+ }
+ }
+ }
+ clk.CommandGroup = CommandGroup;
+ class Program {
+ constructor(argKey, args = {}) {
+ this.mainCommand = new CommandGroup(argKey, null, {
+ help: args.help,
+ });
+ this.mainCommand.flag("help", ["-h", "--help"], {
+ help: "Show this message and exit.",
+ });
+ }
+ run(cmdlineArgs) {
+ let args;
+ if (cmdlineArgs) {
+ args = cmdlineArgs;
+ }
+ else {
+ args = process__default["default"].argv.slice(1);
+ }
+ if (args.length < 1) {
+ console.error("Error while parsing command line arguments: not enough arguments");
+ process__default["default"].exit(-1);
+ }
+ const progname = nodejs_path__default["default"].basename(args[0]);
+ const rest = args.slice(1);
+ this.mainCommand.run(progname, [], rest, {});
+ }
+ subcommand(argKey, name, args = {}) {
+ const cmd = this.mainCommand.subcommand(argKey, name, args);
+ return cmd;
+ }
+ requiredOption(name, flagspec, conv, args = {}) {
+ this.mainCommand.requiredOption(name, flagspec, conv, args);
+ return this;
+ }
+ maybeOption(name, flagspec, conv, args = {}) {
+ this.mainCommand.maybeOption(name, flagspec, conv, args);
+ return this;
+ }
+ /**
+ * Add a flag (option without value) to the program.
+ */
+ flag(name, flagspec, args = {}) {
+ this.mainCommand.flag(name, flagspec, args);
+ return this;
+ }
+ /**
+ * Add a required positional argument to the program.
+ */
+ requiredArgument(name, conv, args = {}) {
+ this.mainCommand.requiredArgument(name, conv, args);
+ return this;
+ }
+ /**
+ * Add an optional argument to the program.
+ */
+ maybeArgument(name, conv, args = {}) {
+ this.mainCommand.maybeArgument(name, conv, args);
+ return this;
+ }
+ action(f) {
+ this.mainCommand.action(f);
+ }
+ }
+ clk.Program = Program;
+ function program(argKey, args = {}) {
+ return new Program(argKey, args);
+ }
+ clk.program = program;
+ function prompt(question) {
+ const stdinReadline = readline__default["default"].createInterface({
+ input: process__default["default"].stdin,
+ output: process__default["default"].stdout,
+ });
+ return new Promise((resolve, reject) => {
+ stdinReadline.question(question, (res) => {
+ resolve(res);
+ stdinReadline.close();
+ });
+ });
+ }
+ clk.prompt = prompt;
+})(clk || (clk = {}));
+
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+initNodePrng();
+
+/*
+ This file is part of GNU Taler
+ (C) 2019-2020 Taler Systems SA
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+function makeErrorDetail(code, detail, hint) {
+ if (!hint && !detail.hint) {
+ hint = getDefaultHint(code);
+ }
+ return Object.assign({ code, hint }, detail);
+}
+function makePendingOperationFailedError(innerError, tag, uid) {
+ return TalerError.fromDetail(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED, {
+ innerError,
+ transactionId: `${tag}:${uid}`,
+ });
+}
+function getDefaultHint(code) {
+ const errName = TalerErrorCode[code];
+ if (errName) {
+ return `Error (${errName})`;
+ }
+ else {
+ return `Error (<unknown>)`;
+ }
+}
+class TalerProtocolViolationError extends Error {
+ constructor(hint) {
+ let msg;
+ if (hint) {
+ msg = `Taler protocol violation error (${hint})`;
+ }
+ else {
+ msg = `Taler protocol violation error`;
+ }
+ super(msg);
+ Object.setPrototypeOf(this, TalerProtocolViolationError.prototype);
+ }
+}
+class TalerError extends Error {
+ constructor(d) {
+ var _a;
+ super((_a = d.hint) !== null && _a !== void 0 ? _a : `Error (code ${d.code})`);
+ this.errorDetail = d;
+ Object.setPrototypeOf(this, TalerError.prototype);
+ }
+ static fromDetail(code, detail, hint) {
+ if (!hint) {
+ hint = getDefaultHint(code);
+ }
+ return new TalerError(Object.assign({ code, hint }, detail));
+ }
+ static fromUncheckedDetail(d) {
+ return new TalerError(Object.assign({}, d));
+ }
+ static fromException(e) {
+ const errDetail = getErrorDetailFromException(e);
+ return new TalerError(errDetail);
+ }
+ hasErrorCode(code) {
+ return this.errorDetail.code === code;
+ }
+}
+/**
+ * Convert an exception (or anything that was thrown) into
+ * a TalerErrorDetail object.
+ */
+function getErrorDetailFromException(e) {
+ if (e instanceof TalerError) {
+ return e.errorDetail;
+ }
+ if (e instanceof Error) {
+ const err = makeErrorDetail(TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION, {
+ stack: e.stack,
+ }, `unexpected exception (message: ${e.message})`);
+ return err;
+ }
+ // Something was thrown that is not even an exception!
+ // Try to stringify it.
+ let excString;
+ try {
+ excString = e.toString();
+ }
+ catch (e) {
+ // Something went horribly wrong.
+ excString = "can't stringify exception";
+ }
+ const err = makeErrorDetail(TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION, {}, `unexpected exception (not an exception, ${excString})`);
+ return err;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 GNUnet e.V.
+
+ 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/>
+ */
+/**
+ * Get an unresolved promise together with its extracted resolve / reject
+ * function.
+ */
+function openPromise$1() {
+ let resolve = null;
+ let reject = null;
+ const promise = new Promise((res, rej) => {
+ resolve = res;
+ reject = rej;
+ });
+ if (!(resolve && reject)) {
+ // Never happens, unless JS implementation is broken
+ throw Error();
+ }
+ return { resolve, reject, promise };
+}
+class AsyncCondition$1 {
+ constructor() {
+ const op = openPromise$1();
+ this._waitPromise = op.promise;
+ this._resolveWaitPromise = op.resolve;
+ }
+ wait() {
+ return this._waitPromise;
+ }
+ trigger() {
+ this._resolveWaitPromise();
+ const op = openPromise$1();
+ this._waitPromise = op.promise;
+ this._resolveWaitPromise = op.resolve;
+ }
+}
+
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ 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/>
+ */
+const logger$u = new Logger("query.ts");
+/**
+ * Exception that should be thrown by client code to abort a transaction.
+ */
+const TransactionAbort = Symbol("transaction_abort");
+function requestToPromise(req) {
+ const stack = Error("Failed request was started here.");
+ return new Promise((resolve, reject) => {
+ req.onsuccess = () => {
+ resolve(req.result);
+ };
+ req.onerror = () => {
+ console.error("error in DB request", req.error);
+ reject(req.error);
+ console.error("Request failed:", stack);
+ };
+ });
+}
+class TransactionAbortedError extends Error {
+ constructor(m) {
+ super(m);
+ // Set the prototype explicitly.
+ Object.setPrototypeOf(this, TransactionAbortedError.prototype);
+ }
+}
+class ResultStream {
+ constructor(req) {
+ this.req = req;
+ this.gotCursorEnd = false;
+ this.awaitingResult = false;
+ this.awaitingResult = true;
+ let p = openPromise$1();
+ this.currentPromise = p.promise;
+ req.onsuccess = () => {
+ if (!this.awaitingResult) {
+ throw Error("BUG: invariant violated");
+ }
+ const cursor = req.result;
+ if (cursor) {
+ this.awaitingResult = false;
+ p.resolve();
+ p = openPromise$1();
+ this.currentPromise = p.promise;
+ }
+ else {
+ this.gotCursorEnd = true;
+ p.resolve();
+ }
+ };
+ req.onerror = () => {
+ p.reject(req.error);
+ };
+ }
+ async toArray() {
+ const arr = [];
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ arr.push(x.value);
+ }
+ else {
+ break;
+ }
+ }
+ return arr;
+ }
+ async map(f) {
+ const arr = [];
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ arr.push(f(x.value));
+ }
+ else {
+ break;
+ }
+ }
+ return arr;
+ }
+ async mapAsync(f) {
+ const arr = [];
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ arr.push(await f(x.value));
+ }
+ else {
+ break;
+ }
+ }
+ return arr;
+ }
+ async forEachAsync(f) {
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ await f(x.value);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ async forEach(f) {
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ f(x.value);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ async filter(f) {
+ const arr = [];
+ while (true) {
+ const x = await this.next();
+ if (x.hasValue) {
+ if (f(x.value)) {
+ arr.push(x.value);
+ }
+ }
+ else {
+ break;
+ }
+ }
+ return arr;
+ }
+ async next() {
+ if (this.gotCursorEnd) {
+ return { hasValue: false };
+ }
+ if (!this.awaitingResult) {
+ const cursor = this.req.result;
+ if (!cursor) {
+ throw Error("assertion failed");
+ }
+ this.awaitingResult = true;
+ cursor.continue();
+ }
+ await this.currentPromise;
+ if (this.gotCursorEnd) {
+ return { hasValue: false };
+ }
+ const cursor = this.req.result;
+ if (!cursor) {
+ throw Error("assertion failed");
+ }
+ return { hasValue: true, value: cursor.value };
+ }
+}
+/**
+ * Return a promise that resolves to the opened IndexedDB database.
+ */
+function openDatabase(idbFactory, databaseName, databaseVersion, onVersionChange, onUpgradeNeeded) {
+ return new Promise((resolve, reject) => {
+ const req = idbFactory.open(databaseName, databaseVersion);
+ req.onerror = (e) => {
+ logger$u.error("database error", e);
+ reject(new Error("database error"));
+ };
+ req.onsuccess = (e) => {
+ req.result.onversionchange = (evt) => {
+ logger$u.info(`handling live db version change from ${evt.oldVersion} to ${evt.newVersion}`);
+ req.result.close();
+ onVersionChange();
+ };
+ resolve(req.result);
+ };
+ req.onupgradeneeded = (e) => {
+ const db = req.result;
+ const newVersion = e.newVersion;
+ if (!newVersion) {
+ throw Error("upgrade needed, but new version unknown");
+ }
+ const transaction = req.transaction;
+ if (!transaction) {
+ throw Error("no transaction handle available in upgrade handler");
+ }
+ onUpgradeNeeded(db, e.oldVersion, newVersion, transaction);
+ };
+ });
+}
+function describeContents(options) {
+ return {
+ keyPath: options.keyPath,
+ _dummy: undefined,
+ autoIncrement: options.autoIncrement,
+ versionAdded: options.versionAdded,
+ };
+}
+function describeIndex(name, keyPath, options = {}) {
+ return {
+ keyPath,
+ name,
+ multiEntry: options.multiEntry,
+ unique: options.unique,
+ versionAdded: options.versionAdded,
+ };
+}
+const storeWithIndexesSymbol = Symbol("StoreWithIndexesMark");
+function describeStore(name, s, m) {
+ return {
+ storeName: name,
+ store: s,
+ indexMap: m,
+ mark: storeWithIndexesSymbol,
+ };
+}
+function runTx(tx, arg, f) {
+ const stack = Error("Failed transaction was started here.");
+ return new Promise((resolve, reject) => {
+ let funResult = undefined;
+ let gotFunResult = false;
+ let transactionException = undefined;
+ tx.oncomplete = () => {
+ // This is a fatal error: The transaction completed *before*
+ // the transaction function returned. Likely, the transaction
+ // function waited on a promise that is *not* resolved in the
+ // microtask queue, thus triggering the auto-commit behavior.
+ // Unfortunately, the auto-commit behavior of IDB can't be switched
+ // of. There are some proposals to add this functionality in the future.
+ if (!gotFunResult) {
+ const msg = "BUG: transaction closed before transaction function returned";
+ logger$u.error(msg);
+ logger$u.error(`${stack.stack}`);
+ reject(Error(msg));
+ }
+ resolve(funResult);
+ };
+ tx.onerror = () => {
+ logger$u.error("error in transaction");
+ logger$u.error(`${stack.stack}`);
+ };
+ tx.onabort = () => {
+ let msg;
+ if (tx.error) {
+ msg = `Transaction aborted (transaction error): ${tx.error}`;
+ }
+ else if (transactionException !== undefined) {
+ msg = `Transaction aborted (exception thrown): ${transactionException}`;
+ }
+ else {
+ msg = "Transaction aborted (no DB error)";
+ }
+ logger$u.error(msg);
+ logger$u.error(`${stack.stack}`);
+ reject(new TransactionAbortedError(msg));
+ };
+ const resP = Promise.resolve().then(() => f(arg, tx));
+ resP
+ .then((result) => {
+ gotFunResult = true;
+ funResult = result;
+ })
+ .catch((e) => {
+ if (e == TransactionAbort) {
+ logger$u.trace("aborting transaction");
+ }
+ else {
+ transactionException = e;
+ console.error("Transaction failed:", e);
+ console.error(stack);
+ tx.abort();
+ }
+ })
+ .catch((e) => {
+ console.error("fatal: aborting transaction failed", e);
+ });
+ });
+}
+function makeReadContext(tx, storePick) {
+ const ctx = {};
+ for (const storeAlias in storePick) {
+ const indexes = {};
+ const swi = storePick[storeAlias];
+ const storeName = swi.storeName;
+ for (const indexAlias in storePick[storeAlias].indexMap) {
+ const indexDescriptor = storePick[storeAlias].indexMap[indexAlias];
+ const indexName = indexDescriptor.name;
+ indexes[indexAlias] = {
+ get(key) {
+ const req = tx.objectStore(storeName).index(indexName).get(key);
+ return requestToPromise(req);
+ },
+ iter(query) {
+ const req = tx
+ .objectStore(storeName)
+ .index(indexName)
+ .openCursor(query);
+ return new ResultStream(req);
+ },
+ getAll(query, count) {
+ const req = tx
+ .objectStore(storeName)
+ .index(indexName)
+ .getAll(query, count);
+ return requestToPromise(req);
+ },
+ };
+ }
+ ctx[storeAlias] = {
+ indexes,
+ get(key) {
+ const req = tx.objectStore(storeName).get(key);
+ return requestToPromise(req);
+ },
+ iter(query) {
+ const req = tx.objectStore(storeName).openCursor(query);
+ return new ResultStream(req);
+ },
+ };
+ }
+ return ctx;
+}
+function makeWriteContext(tx, storePick) {
+ const ctx = {};
+ for (const storeAlias in storePick) {
+ const indexes = {};
+ const swi = storePick[storeAlias];
+ const storeName = swi.storeName;
+ for (const indexAlias in storePick[storeAlias].indexMap) {
+ const indexDescriptor = storePick[storeAlias].indexMap[indexAlias];
+ const indexName = indexDescriptor.name;
+ indexes[indexAlias] = {
+ get(key) {
+ const req = tx.objectStore(storeName).index(indexName).get(key);
+ return requestToPromise(req);
+ },
+ iter(query) {
+ const req = tx
+ .objectStore(storeName)
+ .index(indexName)
+ .openCursor(query);
+ return new ResultStream(req);
+ },
+ getAll(query, count) {
+ const req = tx
+ .objectStore(storeName)
+ .index(indexName)
+ .getAll(query, count);
+ return requestToPromise(req);
+ },
+ };
+ }
+ ctx[storeAlias] = {
+ indexes,
+ get(key) {
+ const req = tx.objectStore(storeName).get(key);
+ return requestToPromise(req);
+ },
+ iter(query) {
+ const req = tx.objectStore(storeName).openCursor(query);
+ return new ResultStream(req);
+ },
+ async add(r) {
+ const req = tx.objectStore(storeName).add(r);
+ const key = await requestToPromise(req);
+ return {
+ key: key,
+ };
+ },
+ async put(r) {
+ const req = tx.objectStore(storeName).put(r);
+ const key = await requestToPromise(req);
+ return {
+ key: key,
+ };
+ },
+ delete(k) {
+ const req = tx.objectStore(storeName).delete(k);
+ return requestToPromise(req);
+ },
+ };
+ }
+ return ctx;
+}
+/**
+ * Type-safe access to a database with a particular store map.
+ *
+ * A store map is the metadata that describes the store.
+ */
+class DbAccess {
+ constructor(db, stores) {
+ this.db = db;
+ this.stores = stores;
+ }
+ idbHandle() {
+ return this.db;
+ }
+ /**
+ * Run a transaction with all object stores.
+ */
+ mktxAll() {
+ const storeNames = [];
+ const accessibleStores = {};
+ for (let i = 0; i < this.db.objectStoreNames.length; i++) {
+ const sn = this.db.objectStoreNames[i];
+ const swi = this.stores[sn];
+ if (!swi) {
+ throw Error(`store metadata not available (${sn})`);
+ }
+ storeNames.push(sn);
+ accessibleStores[sn] = swi;
+ }
+ const runReadOnly = (txf) => {
+ const tx = this.db.transaction(storeNames, "readonly");
+ const readContext = makeReadContext(tx, accessibleStores);
+ return runTx(tx, readContext, txf);
+ };
+ const runReadWrite = (txf) => {
+ const tx = this.db.transaction(storeNames, "readwrite");
+ const writeContext = makeWriteContext(tx, accessibleStores);
+ return runTx(tx, writeContext, txf);
+ };
+ return {
+ runReadOnly,
+ runReadWrite,
+ };
+ }
+ /**
+ * Run a transaction with selected object stores.
+ *
+ * The {@link namePicker} must be a function that selects a list of object
+ * stores from all available object stores.
+ */
+ mktx(namePicker) {
+ const storeNames = [];
+ const accessibleStores = {};
+ const storePick = namePicker(this.stores);
+ if (typeof storePick !== "object" || storePick === null) {
+ throw Error();
+ }
+ for (const swiPicked of storePick) {
+ const swi = swiPicked;
+ if (swi.mark !== storeWithIndexesSymbol) {
+ throw Error("invalid store descriptor returned from selector function");
+ }
+ storeNames.push(swi.storeName);
+ accessibleStores[swi.storeName] = swi;
+ }
+ const runReadOnly = (txf) => {
+ const tx = this.db.transaction(storeNames, "readonly");
+ const readContext = makeReadContext(tx, accessibleStores);
+ return runTx(tx, readContext, txf);
+ };
+ const runReadWrite = (txf) => {
+ const tx = this.db.transaction(storeNames, "readwrite");
+ const writeContext = makeWriteContext(tx, accessibleStores);
+ return runTx(tx, writeContext, txf);
+ };
+ return {
+ runReadOnly,
+ runReadWrite,
+ };
+ }
+}
+
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ 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/>
+ */
+const logger$t = new Logger("http.ts");
+const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
+/**
+ * Headers, roughly modeled after the fetch API's headers object.
+ */
+class Headers {
+ constructor() {
+ this.headerMap = new Map();
+ }
+ get(name) {
+ const r = this.headerMap.get(name.toLowerCase());
+ if (r) {
+ return r;
+ }
+ return null;
+ }
+ set(name, value) {
+ const normalizedName = name.toLowerCase();
+ const existing = this.headerMap.get(normalizedName);
+ if (existing !== undefined) {
+ this.headerMap.set(normalizedName, existing + "," + value);
+ }
+ else {
+ this.headerMap.set(normalizedName, value);
+ }
+ }
+ toJSON() {
+ const m = {};
+ this.headerMap.forEach((v, k) => (m[k] = v));
+ return m;
+ }
+}
+async function readTalerErrorResponse(httpResponse) {
+ const errJson = await httpResponse.json();
+ const talerErrorCode = errJson.code;
+ if (typeof talerErrorCode !== "number") {
+ logger$t.warn(`malformed error response (status ${httpResponse.status}): ${j2s(errJson)}`);
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ }, "Error response did not contain error code");
+ }
+ return errJson;
+}
+async function readUnexpectedResponseDetails(httpResponse) {
+ const errJson = await httpResponse.json();
+ const talerErrorCode = errJson.code;
+ if (typeof talerErrorCode !== "number") {
+ return makeErrorDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ }, "Error response did not contain error code");
+ }
+ return makeErrorDetail(TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, {
+ requestUrl: httpResponse.requestUrl,
+ httpStatusCode: httpResponse.status,
+ errorResponse: errJson,
+ }, `Unexpected HTTP status (${httpResponse.status}) in response`);
+}
+async function readSuccessResponseJsonOrErrorCode(httpResponse, codec) {
+ if (!(httpResponse.status >= 200 && httpResponse.status < 300)) {
+ return {
+ isError: true,
+ talerErrorResponse: await readTalerErrorResponse(httpResponse),
+ };
+ }
+ const respJson = await httpResponse.json();
+ let parsedResponse;
+ try {
+ parsedResponse = codec.decode(respJson);
+ }
+ catch (e) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ requestUrl: httpResponse.requestUrl,
+ httpStatusCode: httpResponse.status,
+ validationError: e.toString(),
+ }, "Response invalid");
+ }
+ return {
+ isError: false,
+ response: parsedResponse,
+ };
+}
+function getHttpResponseErrorDetails(httpResponse) {
+ return {
+ requestUrl: httpResponse.requestUrl,
+ httpStatusCode: httpResponse.status,
+ };
+}
+function throwUnexpectedRequestError(httpResponse, talerErrorResponse) {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, {
+ requestUrl: httpResponse.requestUrl,
+ httpStatusCode: httpResponse.status,
+ errorResponse: talerErrorResponse,
+ }, `Unexpected HTTP status ${httpResponse.status} in response`);
+}
+async function readSuccessResponseJsonOrThrow(httpResponse, codec) {
+ const r = await readSuccessResponseJsonOrErrorCode(httpResponse, codec);
+ if (!r.isError) {
+ return r.response;
+ }
+ throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
+}
+async function readSuccessResponseTextOrErrorCode(httpResponse) {
+ if (!(httpResponse.status >= 200 && httpResponse.status < 300)) {
+ const errJson = await httpResponse.json();
+ const talerErrorCode = errJson.code;
+ if (typeof talerErrorCode !== "number") {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ httpStatusCode: httpResponse.status,
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ }, "Error response did not contain error code");
+ }
+ return {
+ isError: true,
+ talerErrorResponse: errJson,
+ };
+ }
+ const respJson = await httpResponse.text();
+ return {
+ isError: false,
+ response: respJson,
+ };
+}
+async function checkSuccessResponseOrThrow(httpResponse) {
+ if (!(httpResponse.status >= 200 && httpResponse.status < 300)) {
+ const errJson = await httpResponse.json();
+ const talerErrorCode = errJson.code;
+ if (typeof talerErrorCode !== "number") {
+ throw TalerError.fromDetail(TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, {
+ httpStatusCode: httpResponse.status,
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ }, "Error response did not contain error code");
+ }
+ throwUnexpectedRequestError(httpResponse, errJson);
+ }
+}
+async function readSuccessResponseTextOrThrow(httpResponse) {
+ const r = await readSuccessResponseTextOrErrorCode(httpResponse);
+ if (!r.isError) {
+ return r.response;
+ }
+ throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
+}
+/**
+ * Get the timestamp at which the response's content is considered expired.
+ */
+function getExpiry(httpResponse, opt) {
+ var _a;
+ const expiryDateMs = new Date((_a = httpResponse.headers.get("expiry")) !== null && _a !== void 0 ? _a : "").getTime();
+ let t;
+ if (Number.isNaN(expiryDateMs)) {
+ t = AbsoluteTime.now();
+ }
+ else {
+ t = {
+ t_ms: expiryDateMs,
+ };
+ }
+ if (opt.minDuration) {
+ const t2 = AbsoluteTime.addDuration(AbsoluteTime.now(), opt.minDuration);
+ return AbsoluteTime.max(t, t2);
+ }
+ return t;
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * Protocol version spoken with the exchange.
+ *
+ * Uses libtool's current:revision:age versioning.
+ */
+const WALLET_EXCHANGE_PROTOCOL_VERSION = "12:0:0";
+/**
+ * Protocol version spoken with the merchant.
+ *
+ * Uses libtool's current:revision:age versioning.
+ */
+const WALLET_MERCHANT_PROTOCOL_VERSION = "2:0:1";
+/**
+ * Protocol version spoken with the merchant.
+ *
+ * Uses libtool's current:revision:age versioning.
+ */
+const WALLET_BANK_INTEGRATION_PROTOCOL_VERSION = "0:0:0";
+
+/*
+ This file is part of GNU Taler
+ (C) 2021-2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * This file contains the database schema of the Taler wallet together
+ * with some helper functions.
+ *
+ * Some design considerations:
+ * - By convention, each object store must have a corresponding "<Name>Record"
+ * interface defined for it.
+ * - For records that represent operations, there should be exactly
+ * one top-level enum field that indicates the status of the operation.
+ * This field should be present even if redundant, because the field
+ * will have an index.
+ * - Amounts are stored as strings, except when they are needed for
+ * indexing.
+ * - Every record that has a corresponding transaction item must have
+ * an index for a mandatory timestamp field.
+ * - Optional fields should be avoided, use "T | undefined" instead.
+ * - Do all records have some obvious, indexed field that can
+ * be used for range queries?
+ *
+ * @author Florian Dold <dold@taler.net>
+ */
+/**
+ * Name of the Taler database. This is effectively the major
+ * version of the DB schema. Whenever it changes, custom import logic
+ * for all previous versions must be written, which should be
+ * avoided.
+ */
+const TALER_DB_NAME = "taler-wallet-main-v9";
+/**
+ * Name of the metadata database. This database is used
+ * to track major migrations of the main Taler database.
+ *
+ * (Minor migrations are handled via upgrade transactions.)
+ */
+const TALER_META_DB_NAME = "taler-wallet-meta";
+const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
+/**
+ * Current database minor version, should be incremented
+ * each time we do minor schema changes on the database.
+ * A change is considered minor when fields are added in a
+ * backwards-compatible way or object stores and indices
+ * are added.
+ */
+const WALLET_DB_MINOR_VERSION = 1;
+/**
+ * Ranges for operation status fields.
+ *
+ * All individual enums should make sure that the values they
+ * defined are in the right range.
+ */
+var OperationStatusRange;
+(function (OperationStatusRange) {
+ // Operations that need to be actively processed.
+ OperationStatusRange[OperationStatusRange["ACTIVE_START"] = 10] = "ACTIVE_START";
+ OperationStatusRange[OperationStatusRange["ACTIVE_END"] = 29] = "ACTIVE_END";
+ // Operations that need user input, but nothing can be done
+ // automatically.
+ OperationStatusRange[OperationStatusRange["USER_ATTENTION_START"] = 30] = "USER_ATTENTION_START";
+ OperationStatusRange[OperationStatusRange["USER_ATTENTION_END"] = 49] = "USER_ATTENTION_END";
+ // Operations that don't need any attention or processing.
+ OperationStatusRange[OperationStatusRange["DORMANT_START"] = 50] = "DORMANT_START";
+ OperationStatusRange[OperationStatusRange["DORMANT_END"] = 69] = "DORMANT_END";
+})(OperationStatusRange || (OperationStatusRange = {}));
+/**
+ * Status of a withdrawal.
+ */
+var WithdrawalGroupStatus;
+(function (WithdrawalGroupStatus) {
+ /**
+ * Reserve must be registered with the bank.
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["RegisteringBank"] = 10] = "RegisteringBank";
+ /**
+ * We've registered reserve's information with the bank
+ * and are now waiting for the user to confirm the withdraw
+ * with the bank (typically 2nd factor auth).
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["WaitConfirmBank"] = 11] = "WaitConfirmBank";
+ /**
+ * Querying reserve status with the exchange.
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["QueryingStatus"] = 12] = "QueryingStatus";
+ /**
+ * Ready for withdrawal.
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["Ready"] = 13] = "Ready";
+ /**
+ * The corresponding withdraw record has been created.
+ * No further processing is done, unless explicitly requested
+ * by the user.
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["Finished"] = 50] = "Finished";
+ /**
+ * The bank aborted the withdrawal.
+ */
+ WithdrawalGroupStatus[WithdrawalGroupStatus["BankAborted"] = 51] = "BankAborted";
+})(WithdrawalGroupStatus || (WithdrawalGroupStatus = {}));
+/**
+ * Status of a denomination.
+ */
+var DenominationVerificationStatus;
+(function (DenominationVerificationStatus) {
+ /**
+ * Verification was delayed.
+ */
+ DenominationVerificationStatus[DenominationVerificationStatus["Unverified"] = 10] = "Unverified";
+ /**
+ * Verified as valid.
+ */
+ DenominationVerificationStatus[DenominationVerificationStatus["VerifiedGood"] = 50] = "VerifiedGood";
+ /**
+ * Verified as invalid.
+ */
+ DenominationVerificationStatus[DenominationVerificationStatus["VerifiedBad"] = 51] = "VerifiedBad";
+})(DenominationVerificationStatus || (DenominationVerificationStatus = {}));
+var DenominationRecord;
+(function (DenominationRecord) {
+ function getValue(d) {
+ return {
+ currency: d.currency,
+ fraction: d.amountFrac,
+ value: d.amountVal,
+ };
+ }
+ DenominationRecord.getValue = getValue;
+ function toDenomInfo(d) {
+ return {
+ denomPub: d.denomPub,
+ denomPubHash: d.denomPubHash,
+ feeDeposit: Amounts.stringify(d.fees.feeDeposit),
+ feeRefresh: Amounts.stringify(d.fees.feeRefresh),
+ feeRefund: Amounts.stringify(d.fees.feeRefund),
+ feeWithdraw: Amounts.stringify(d.fees.feeWithdraw),
+ stampExpireDeposit: d.stampExpireDeposit,
+ stampExpireLegal: d.stampExpireLegal,
+ stampExpireWithdraw: d.stampExpireWithdraw,
+ stampStart: d.stampStart,
+ value: Amounts.stringify(DenominationRecord.getValue(d)),
+ exchangeBaseUrl: d.exchangeBaseUrl,
+ };
+ }
+ DenominationRecord.toDenomInfo = toDenomInfo;
+})(DenominationRecord || (DenominationRecord = {}));
+var PlanchetStatus;
+(function (PlanchetStatus) {
+ PlanchetStatus[PlanchetStatus["Pending"] = 10] = "Pending"; /* ACTIVE_START */
+ PlanchetStatus[PlanchetStatus["KycRequired"] = 11] = "KycRequired"; /* ACTIVE_START + 1 */
+ PlanchetStatus[PlanchetStatus["WithdrawalDone"] = 50] = "WithdrawalDone"; /* DORMANT_START */
+})(PlanchetStatus || (PlanchetStatus = {}));
+var CoinSourceType;
+(function (CoinSourceType) {
+ CoinSourceType["Withdraw"] = "withdraw";
+ CoinSourceType["Refresh"] = "refresh";
+ CoinSourceType["Tip"] = "tip";
+})(CoinSourceType || (CoinSourceType = {}));
+var RefreshCoinStatus;
+(function (RefreshCoinStatus) {
+ RefreshCoinStatus[RefreshCoinStatus["Pending"] = 10] = "Pending";
+ RefreshCoinStatus[RefreshCoinStatus["Finished"] = 50] = "Finished";
+ /**
+ * The refresh for this coin has been frozen, because of a permanent error.
+ * More info in lastErrorPerCoin.
+ */
+ RefreshCoinStatus[RefreshCoinStatus["Frozen"] = 51] = "Frozen";
+})(RefreshCoinStatus || (RefreshCoinStatus = {}));
+var OperationStatus;
+(function (OperationStatus) {
+ OperationStatus[OperationStatus["Finished"] = 50] = "Finished";
+ OperationStatus[OperationStatus["Pending"] = 10] = "Pending";
+})(OperationStatus || (OperationStatus = {}));
+var RefreshOperationStatus;
+(function (RefreshOperationStatus) {
+ RefreshOperationStatus[RefreshOperationStatus["Pending"] = 10] = "Pending"; /* ACTIVE_START */
+ RefreshOperationStatus[RefreshOperationStatus["Finished"] = 50] = "Finished"; /* DORMANT_START */
+ RefreshOperationStatus[RefreshOperationStatus["FinishedWithError"] = 51] = "FinishedWithError"; /* DORMANT_START + 1 */
+})(RefreshOperationStatus || (RefreshOperationStatus = {}));
+var RefundState;
+(function (RefundState) {
+ RefundState["Failed"] = "failed";
+ RefundState["Applied"] = "applied";
+ RefundState["Pending"] = "pending";
+})(RefundState || (RefundState = {}));
+var RefundReason;
+(function (RefundReason) {
+ /**
+ * Normal refund given by the merchant.
+ */
+ RefundReason["NormalRefund"] = "normal-refund";
+ /**
+ * Refund from an aborted payment.
+ */
+ RefundReason["AbortRefund"] = "abort-pay-refund";
+})(RefundReason || (RefundReason = {}));
+var PurchaseStatus;
+(function (PurchaseStatus) {
+ /**
+ * Not downloaded yet.
+ */
+ PurchaseStatus[PurchaseStatus["DownloadingProposal"] = 10] = "DownloadingProposal";
+ /**
+ * The user has accepted the proposal.
+ */
+ PurchaseStatus[PurchaseStatus["Paying"] = 11] = "Paying";
+ /**
+ * Currently in the process of aborting with a refund.
+ */
+ PurchaseStatus[PurchaseStatus["AbortingWithRefund"] = 12] = "AbortingWithRefund";
+ /**
+ * Paying a second time, likely with different session ID
+ */
+ PurchaseStatus[PurchaseStatus["PayingReplay"] = 13] = "PayingReplay";
+ /**
+ * Query for refunds (until query succeeds).
+ */
+ PurchaseStatus[PurchaseStatus["QueryingRefund"] = 14] = "QueryingRefund";
+ /**
+ * Query for refund (until auto-refund deadline is reached).
+ */
+ PurchaseStatus[PurchaseStatus["QueryingAutoRefund"] = 15] = "QueryingAutoRefund";
+ /**
+ * Proposal downloaded, but the user needs to accept/reject it.
+ */
+ PurchaseStatus[PurchaseStatus["Proposed"] = 30] = "Proposed";
+ /**
+ * The user has rejected the proposal.
+ */
+ PurchaseStatus[PurchaseStatus["ProposalRefused"] = 50] = "ProposalRefused";
+ /**
+ * Downloading or processing the proposal has failed permanently.
+ */
+ PurchaseStatus[PurchaseStatus["ProposalDownloadFailed"] = 51] = "ProposalDownloadFailed";
+ /**
+ * Downloaded proposal was detected as a re-purchase.
+ */
+ PurchaseStatus[PurchaseStatus["RepurchaseDetected"] = 52] = "RepurchaseDetected";
+ /**
+ * The payment has been aborted.
+ */
+ PurchaseStatus[PurchaseStatus["PaymentAbortFinished"] = 53] = "PaymentAbortFinished";
+ /**
+ * Payment was successful.
+ */
+ PurchaseStatus[PurchaseStatus["Paid"] = 54] = "Paid";
+})(PurchaseStatus || (PurchaseStatus = {}));
+var ConfigRecordKey;
+(function (ConfigRecordKey) {
+ ConfigRecordKey["WalletBackupState"] = "walletBackupState";
+ ConfigRecordKey["CurrencyDefaultsApplied"] = "currencyDefaultsApplied";
+ ConfigRecordKey["DevMode"] = "devMode";
+})(ConfigRecordKey || (ConfigRecordKey = {}));
+var BackupProviderStateTag;
+(function (BackupProviderStateTag) {
+ BackupProviderStateTag["Provisional"] = "provisional";
+ BackupProviderStateTag["Ready"] = "ready";
+ BackupProviderStateTag["Retrying"] = "retrying";
+})(BackupProviderStateTag || (BackupProviderStateTag = {}));
+var PeerPushPaymentInitiationStatus;
+(function (PeerPushPaymentInitiationStatus) {
+ /**
+ * Initiated, but no purse created yet.
+ */
+ PeerPushPaymentInitiationStatus[PeerPushPaymentInitiationStatus["Initiated"] = 10] = "Initiated"; /* ACTIVE_START */
+ PeerPushPaymentInitiationStatus[PeerPushPaymentInitiationStatus["PurseCreated"] = 50] = "PurseCreated"; /* DORMANT_START */
+})(PeerPushPaymentInitiationStatus || (PeerPushPaymentInitiationStatus = {}));
+var PeerPullPaymentIncomingStatus;
+(function (PeerPullPaymentIncomingStatus) {
+ PeerPullPaymentIncomingStatus[PeerPullPaymentIncomingStatus["Proposed"] = 30] = "Proposed"; /* USER_ATTENTION_START */
+ PeerPullPaymentIncomingStatus[PeerPullPaymentIncomingStatus["Accepted"] = 10] = "Accepted"; /* ACTIVE_START */
+ PeerPullPaymentIncomingStatus[PeerPullPaymentIncomingStatus["Paid"] = 50] = "Paid"; /* DORMANT_START */
+})(PeerPullPaymentIncomingStatus || (PeerPullPaymentIncomingStatus = {}));
+/**
+ * Schema definition for the IndexedDB
+ * wallet database.
+ */
+const WalletStoresV1 = {
+ coinAvailability: describeStore("coinAvailability", describeContents({
+ keyPath: ["exchangeBaseUrl", "denomPubHash", "maxAge"],
+ }), {
+ byExchangeAgeAvailability: describeIndex("byExchangeAgeAvailability", [
+ "exchangeBaseUrl",
+ "maxAge",
+ "freshCoinCount",
+ ]),
+ }),
+ coins: describeStore("coins", describeContents({
+ keyPath: "coinPub",
+ }), {
+ byBaseUrl: describeIndex("byBaseUrl", "exchangeBaseUrl"),
+ byDenomPubHash: describeIndex("byDenomPubHash", "denomPubHash"),
+ byExchangeDenomPubHashAndAgeAndStatus: describeIndex("byExchangeDenomPubHashAndAgeAndStatus", ["exchangeBaseUrl", "denomPubHash", "maxAge", "status"]),
+ byCoinEvHash: describeIndex("byCoinEvHash", "coinEvHash"),
+ }),
+ reserves: describeStore("reserves", describeContents({
+ keyPath: "rowId",
+ autoIncrement: true,
+ }), {
+ byReservePub: describeIndex("byReservePub", "reservePub", {}),
+ }),
+ exchangeTos: describeStore("exchangeTos", describeContents({
+ keyPath: ["exchangeBaseUrl", "etag"],
+ }), {}),
+ config: describeStore("config", describeContents({ keyPath: "key" }), {}),
+ auditorTrust: describeStore("auditorTrust", describeContents({
+ keyPath: ["currency", "auditorBaseUrl"],
+ }), {
+ byAuditorPub: describeIndex("byAuditorPub", "auditorPub"),
+ byUid: describeIndex("byUid", "uids", {
+ multiEntry: true,
+ }),
+ }),
+ exchangeTrust: describeStore("exchangeTrust", describeContents({
+ keyPath: ["currency", "exchangeBaseUrl"],
+ }), {
+ byExchangeMasterPub: describeIndex("byExchangeMasterPub", "exchangeMasterPub"),
+ }),
+ denominations: describeStore("denominations", describeContents({
+ keyPath: ["exchangeBaseUrl", "denomPubHash"],
+ }), {
+ byExchangeBaseUrl: describeIndex("byExchangeBaseUrl", "exchangeBaseUrl"),
+ }),
+ exchanges: describeStore("exchanges", describeContents({
+ keyPath: "baseUrl",
+ }), {}),
+ exchangeDetails: describeStore("exchangeDetails", describeContents({
+ keyPath: "rowId",
+ autoIncrement: true,
+ }), {
+ byPointer: describeIndex("byDetailsPointer", ["exchangeBaseUrl", "currency", "masterPublicKey"], {
+ unique: true,
+ }),
+ }),
+ exchangeSignkeys: describeStore("exchangeSignKeys", describeContents({
+ keyPath: ["exchangeDetailsRowId", "signkeyPub"],
+ }), {
+ byExchangeDetailsRowId: describeIndex("byExchangeDetailsRowId", [
+ "exchangeDetailsRowId",
+ ]),
+ }),
+ refreshGroups: describeStore("refreshGroups", describeContents({
+ keyPath: "refreshGroupId",
+ }), {
+ byStatus: describeIndex("byStatus", "operationStatus"),
+ }),
+ recoupGroups: describeStore("recoupGroups", describeContents({
+ keyPath: "recoupGroupId",
+ }), {}),
+ purchases: describeStore("purchases", describeContents({ keyPath: "proposalId" }), {
+ byStatus: describeIndex("byStatus", "purchaseStatus"),
+ byFulfillmentUrl: describeIndex("byFulfillmentUrl", "download.fulfillmentUrl"),
+ byUrlAndOrderId: describeIndex("byUrlAndOrderId", [
+ "merchantBaseUrl",
+ "orderId",
+ ]),
+ }),
+ tips: describeStore("tips", describeContents({ keyPath: "walletTipId" }), {
+ byMerchantTipIdAndBaseUrl: describeIndex("byMerchantTipIdAndBaseUrl", [
+ "merchantTipId",
+ "merchantBaseUrl",
+ ]),
+ }),
+ withdrawalGroups: describeStore("withdrawalGroups", describeContents({
+ keyPath: "withdrawalGroupId",
+ }), {
+ byStatus: describeIndex("byStatus", "status"),
+ byTalerWithdrawUri: describeIndex("byTalerWithdrawUri", "wgInfo.bankInfo.talerWithdrawUri"),
+ }),
+ planchets: describeStore("planchets", describeContents({ keyPath: "coinPub" }), {
+ byGroupAndIndex: describeIndex("byGroupAndIndex", [
+ "withdrawalGroupId",
+ "coinIdx",
+ ]),
+ byGroup: describeIndex("byGroup", "withdrawalGroupId"),
+ byCoinEvHash: describeIndex("byCoinEv", "coinEvHash"),
+ }),
+ bankWithdrawUris: describeStore("bankWithdrawUris", describeContents({
+ keyPath: "talerWithdrawUri",
+ }), {}),
+ backupProviders: describeStore("backupProviders", describeContents({
+ keyPath: "baseUrl",
+ }), {
+ byPaymentProposalId: describeIndex("byPaymentProposalId", "paymentProposalIds", {
+ multiEntry: true,
+ }),
+ }),
+ depositGroups: describeStore("depositGroups", describeContents({
+ keyPath: "depositGroupId",
+ }), {
+ byStatus: describeIndex("byStatus", "operationStatus"),
+ }),
+ tombstones: describeStore("tombstones", describeContents({ keyPath: "id" }), {}),
+ operationRetries: describeStore("operationRetries", describeContents({
+ keyPath: "id",
+ }), {}),
+ ghostDepositGroups: describeStore("ghostDepositGroups", describeContents({
+ keyPath: "contractTermsHash",
+ }), {}),
+ peerPushPaymentIncoming: describeStore("peerPushPaymentIncoming", describeContents({
+ keyPath: "peerPushPaymentIncomingId",
+ }), {
+ byExchangeAndPurse: describeIndex("byExchangeAndPurse", [
+ "exchangeBaseUrl",
+ "pursePub",
+ ]),
+ byStatus: describeIndex("byStatus", "status"),
+ }),
+ peerPullPaymentIncoming: describeStore("peerPullPaymentIncoming", describeContents({
+ keyPath: "peerPullPaymentIncomingId",
+ }), {
+ byExchangeAndPurse: describeIndex("byExchangeAndPurse", [
+ "exchangeBaseUrl",
+ "pursePub",
+ ]),
+ byStatus: describeIndex("byStatus", "status"),
+ }),
+ peerPullPaymentInitiations: describeStore("peerPullPaymentInitiations", describeContents({
+ keyPath: "pursePub",
+ }), {
+ byStatus: describeIndex("byStatus", "status"),
+ }),
+ peerPushPaymentInitiations: describeStore("peerPushPaymentInitiations", describeContents({
+ keyPath: "pursePub",
+ }), {
+ byStatus: describeIndex("byStatus", "status"),
+ }),
+ bankAccounts: describeStore("bankAccounts", describeContents({
+ keyPath: "uri",
+ }), {}),
+ contractTerms: describeStore("contractTerms", describeContents({
+ keyPath: "h",
+ }), {}),
+};
+const walletMetadataStore = {
+ metaConfig: describeStore("metaConfig", describeContents({ keyPath: "key" }), {}),
+};
+function exportDb(db) {
+ const dump = {
+ name: db.name,
+ stores: {},
+ version: db.version,
+ };
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction(Array.from(db.objectStoreNames));
+ tx.addEventListener("complete", () => {
+ resolve(dump);
+ });
+ // tslint:disable-next-line:prefer-for-of
+ for (let i = 0; i < db.objectStoreNames.length; i++) {
+ const name = db.objectStoreNames[i];
+ const storeDump = {};
+ dump.stores[name] = storeDump;
+ tx.objectStore(name)
+ .openCursor()
+ .addEventListener("success", (e) => {
+ const cursor = e.target.result;
+ if (cursor) {
+ storeDump[cursor.key] = cursor.value;
+ cursor.continue();
+ }
+ });
+ }
+ });
+}
+async function recoverFromDump(db, dump) {
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction(Array.from(db.objectStoreNames), "readwrite");
+ tx.addEventListener("complete", () => {
+ resolve();
+ });
+ for (let i = 0; i < db.objectStoreNames.length; i++) {
+ const name = db.objectStoreNames[i];
+ const storeDump = dump.stores[name];
+ if (!storeDump)
+ continue;
+ Object.keys(storeDump).forEach(async (key) => {
+ const value = storeDump[key];
+ if (!value)
+ return;
+ tx.objectStore(name).put(value);
+ });
+ }
+ tx.commit();
+ });
+}
+async function importDb(db, object) {
+ if ("name" in object && "stores" in object && "version" in object) {
+ // looks like a database dump
+ const dump = object;
+ return recoverFromDump(db, dump);
+ }
+ if ("databases" in object && "$types" in object) {
+ // looks like a IDBDatabase
+ const someDatabase = object.databases;
+ if (TALER_META_DB_NAME in someDatabase) {
+ //looks like a taler database
+ const currentMainDbValue = someDatabase[TALER_META_DB_NAME].objectStores.metaConfig.records[0]
+ .value.value;
+ if (currentMainDbValue !== TALER_DB_NAME) {
+ console.log("not the current database version");
+ }
+ const talerDb = someDatabase[currentMainDbValue];
+ const objectStoreNames = Object.keys(talerDb.objectStores);
+ const dump = {
+ name: talerDb.schema.databaseName,
+ version: talerDb.schema.databaseVersion,
+ stores: {},
+ };
+ for (let i = 0; i < objectStoreNames.length; i++) {
+ const name = objectStoreNames[i];
+ const storeDump = {};
+ dump.stores[name] = storeDump;
+ talerDb.objectStores[name].records.map((r) => {
+ const pkey = r.primaryKey;
+ const key = typeof pkey === "string" ? pkey : pkey.join(",");
+ storeDump[key] = r.value;
+ });
+ }
+ return recoverFromDump(db, dump);
+ }
+ }
+ throw Error("could not import database");
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+const logger$s = new Logger("db-utils.ts");
+function upgradeFromStoreMap(storeMap, db, oldVersion, newVersion, upgradeTransaction) {
+ var _a, _b;
+ if (oldVersion === 0) {
+ for (const n in storeMap) {
+ const swi = storeMap[n];
+ const storeDesc = swi.store;
+ const s = db.createObjectStore(swi.storeName, {
+ autoIncrement: storeDesc.autoIncrement,
+ keyPath: storeDesc.keyPath,
+ });
+ for (const indexName in swi.indexMap) {
+ const indexDesc = swi.indexMap[indexName];
+ s.createIndex(indexDesc.name, indexDesc.keyPath, {
+ multiEntry: indexDesc.multiEntry,
+ unique: indexDesc.unique,
+ });
+ }
+ }
+ return;
+ }
+ if (oldVersion === newVersion) {
+ return;
+ }
+ logger$s.info(`upgrading database from ${oldVersion} to ${newVersion}`);
+ for (const n in storeMap) {
+ const swi = storeMap[n];
+ const storeDesc = swi.store;
+ const storeAddedVersion = (_a = storeDesc.versionAdded) !== null && _a !== void 0 ? _a : 0;
+ if (storeAddedVersion <= oldVersion) {
+ continue;
+ }
+ const s = db.createObjectStore(swi.storeName, {
+ autoIncrement: storeDesc.autoIncrement,
+ keyPath: storeDesc.keyPath,
+ });
+ for (const indexName in swi.indexMap) {
+ const indexDesc = swi.indexMap[indexName];
+ const indexAddedVersion = (_b = indexDesc.versionAdded) !== null && _b !== void 0 ? _b : 0;
+ if (indexAddedVersion <= oldVersion) {
+ continue;
+ }
+ s.createIndex(indexDesc.name, indexDesc.keyPath, {
+ multiEntry: indexDesc.multiEntry,
+ unique: indexDesc.unique,
+ });
+ }
+ }
+}
+function promiseFromTransaction(transaction) {
+ return new Promise((resolve, reject) => {
+ transaction.oncomplete = () => {
+ resolve();
+ };
+ transaction.onerror = () => {
+ reject();
+ };
+ });
+}
+/**
+ * Purge all data in the given database.
+ */
+function clearDatabase(db) {
+ // db.objectStoreNames is a DOMStringList, so we need to convert
+ let stores = [];
+ for (let i = 0; i < db.objectStoreNames.length; i++) {
+ stores.push(db.objectStoreNames[i]);
+ }
+ const tx = db.transaction(stores, "readwrite");
+ for (const store of stores) {
+ tx.objectStore(store).clear();
+ }
+ return promiseFromTransaction(tx);
+}
+function onTalerDbUpgradeNeeded(db, oldVersion, newVersion, upgradeTransaction) {
+ upgradeFromStoreMap(WalletStoresV1, db, oldVersion, newVersion);
+}
+function onMetaDbUpgradeNeeded(db, oldVersion, newVersion, upgradeTransaction) {
+ upgradeFromStoreMap(walletMetadataStore, db, oldVersion, newVersion);
+}
+/**
+ * Return a promise that resolves
+ * to the taler wallet db.
+ */
+async function openTalerDatabase(idbFactory, onVersionChange) {
+ const metaDbHandle = await openDatabase(idbFactory, TALER_META_DB_NAME, 1, () => { }, onMetaDbUpgradeNeeded);
+ const metaDb = new DbAccess(metaDbHandle, walletMetadataStore);
+ let currentMainVersion;
+ await metaDb
+ .mktx((stores) => [stores.metaConfig])
+ .runReadWrite(async (tx) => {
+ const dbVersionRecord = await tx.metaConfig.get(CURRENT_DB_CONFIG_KEY);
+ if (!dbVersionRecord) {
+ currentMainVersion = TALER_DB_NAME;
+ await tx.metaConfig.put({
+ key: CURRENT_DB_CONFIG_KEY,
+ value: TALER_DB_NAME,
+ });
+ }
+ else {
+ currentMainVersion = dbVersionRecord.value;
+ }
+ });
+ if (currentMainVersion !== TALER_DB_NAME) {
+ switch (currentMainVersion) {
+ case "taler-wallet-main-v2":
+ case "taler-wallet-main-v3":
+ case "taler-wallet-main-v4": // temporary, we might migrate v4 later
+ case "taler-wallet-main-v5":
+ case "taler-wallet-main-v6":
+ case "taler-wallet-main-v7":
+ case "taler-wallet-main-v8":
+ // We consider this a pre-release
+ // development version, no migration is done.
+ await metaDb
+ .mktx((stores) => [stores.metaConfig])
+ .runReadWrite(async (tx) => {
+ await tx.metaConfig.put({
+ key: CURRENT_DB_CONFIG_KEY,
+ value: TALER_DB_NAME,
+ });
+ });
+ break;
+ default:
+ throw Error(`migration from database ${currentMainVersion} not supported`);
+ }
+ }
+ const mainDbHandle = await openDatabase(idbFactory, TALER_DB_NAME, WALLET_DB_MINOR_VERSION, onVersionChange, onTalerDbUpgradeNeeded);
+ return new DbAccess(mainDbHandle, WalletStoresV1);
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2017-2019 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+const logger$r = new Logger("timer.ts");
+class IntervalHandle {
+ constructor(h) {
+ this.h = h;
+ }
+ clear() {
+ clearInterval(this.h);
+ }
+ /**
+ * Make sure the event loop exits when the timer is the
+ * only event left. Has no effect in the browser.
+ */
+ unref() {
+ if (typeof this.h === "object") {
+ this.h.unref();
+ }
+ }
+}
+class TimeoutHandle {
+ constructor(h) {
+ this.h = h;
+ }
+ clear() {
+ clearTimeout(this.h);
+ }
+ /**
+ * Make sure the event loop exits when the timer is the
+ * only event left. Has no effect in the browser.
+ */
+ unref() {
+ if (typeof this.h === "object") {
+ this.h.unref();
+ }
+ }
+}
+/**
+ * Get a performance counter in nanoseconds.
+ */
+const performanceNow = (() => {
+ // @ts-ignore
+ if (typeof process !== "undefined" && process.hrtime) {
+ return () => {
+ return process.hrtime.bigint();
+ };
+ }
+ // @ts-ignore
+ if (typeof performance !== "undefined") {
+ // @ts-ignore
+ return () => BigInt(Math.floor(performance.now() * 1000)) * BigInt(1000);
+ }
+ return () => BigInt(0);
+})();
+const nullTimerHandle = {
+ clear() {
+ // do nothing
+ return;
+ },
+ unref() {
+ // do nothing
+ return;
+ },
+};
+class SetTimeoutTimerAPI {
+ /**
+ * Call a function every time the delay given in milliseconds passes.
+ */
+ every(delayMs, callback) {
+ return new IntervalHandle(setInterval(callback, delayMs));
+ }
+ /**
+ * Call a function after the delay given in milliseconds passes.
+ */
+ after(delayMs, callback) {
+ return new TimeoutHandle(setTimeout(callback, delayMs));
+ }
+}
+const timer = new SetTimeoutTimerAPI();
+/**
+ * Implementation of [[TimerGroup]] using setTimeout
+ */
+class TimerGroup {
+ constructor(timerApi) {
+ this.timerApi = timerApi;
+ this.stopped = false;
+ this.timerMap = {};
+ this.idGen = 1;
+ }
+ stopCurrentAndFutureTimers() {
+ this.stopped = true;
+ for (const x in this.timerMap) {
+ if (!this.timerMap.hasOwnProperty(x)) {
+ continue;
+ }
+ this.timerMap[x].clear();
+ delete this.timerMap[x];
+ }
+ }
+ resolveAfter(delayMs) {
+ return new Promise((resolve, reject) => {
+ if (delayMs.d_ms !== "forever") {
+ this.after(delayMs.d_ms, () => {
+ resolve();
+ });
+ }
+ });
+ }
+ after(delayMs, callback) {
+ if (this.stopped) {
+ logger$r.warn("dropping timer since timer group is stopped");
+ return nullTimerHandle;
+ }
+ const h = this.timerApi.after(delayMs, callback);
+ const myId = this.idGen++;
+ this.timerMap[myId] = h;
+ const tm = this.timerMap;
+ return {
+ clear() {
+ h.clear();
+ delete tm[myId];
+ },
+ unref() {
+ h.unref();
+ },
+ };
+ }
+ every(delayMs, callback) {
+ if (this.stopped) {
+ logger$r.warn("dropping timer since timer group is stopped");
+ return nullTimerHandle;
+ }
+ const h = this.timerApi.every(delayMs, callback);
+ const myId = this.idGen++;
+ this.timerMap[myId] = h;
+ const tm = this.timerMap;
+ return {
+ clear() {
+ h.clear();
+ delete tm[myId];
+ },
+ unref() {
+ h.unref();
+ },
+ };
+ }
+}
+
+/*
+ This file is part of GNU Taler
+ (C) 2019-2020 Taler Systems SA
+
+ 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/>
+ */
+const logger$q = new Logger("cryptoImplementation.ts");
+/**
+ * Implementation of the Taler crypto interface where every function
+ * always throws. Only useful in practice as a way to iterate through
+ * all possible crypto functions.
+ *
+ * (This list can be easily auto-generated by your favorite IDE).
+ */
+const nullCrypto = {
+ createPlanchet: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ eddsaSign: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ createTipPlanchet: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signTrackTransaction: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ createRecoupRequest: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ createRecoupRefreshRequest: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidPaymentSignature: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidWireFee: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidDenom: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidWireAccount: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidGlobalFees: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ isValidContractTermsSignature: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ createEddsaKeypair: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ eddsaGetPublic: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ unblindDenominationSignature: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ rsaUnblind: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ rsaVerify: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signDepositPermission: function (depositInfo) {
+ throw new Error("Function not implemented.");
+ },
+ deriveRefreshSession: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ hashString: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signCoinLink: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ makeSyncSignature: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ setupRefreshPlanchet: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ rsaBlind: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ keyExchangeEcdheEddsa: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ setupWithdrawalPlanchet: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ ecdheGetPublic: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ setupRefreshTransferPub: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signPurseCreation: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signPurseDeposits: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ encryptContractForMerge: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ decryptContractForMerge: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signPurseMerge: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ encryptContractForDeposit: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ decryptContractForDeposit: function (req) {
+ throw new Error("Function not implemented.");
+ },
+ signReservePurseCreate: function (req) {
+ throw new Error("Function not implemented.");
+ },
+};
+/**
+ * JS-native implementation of the Taler crypto worker operations.
+ */
+const nativeCryptoR = {
+ async eddsaSign(tci, req) {
+ return {
+ sig: encodeCrock(eddsaSign(decodeCrock(req.msg), decodeCrock(req.priv))),
+ };
+ },
+ async rsaBlind(tci, req) {
+ const res = rsaBlind(decodeCrock(req.hm), decodeCrock(req.bks), decodeCrock(req.pub));
+ return {
+ blinded: encodeCrock(res),
+ };
+ },
+ async setupRefreshPlanchet(tci, req) {
+ const transferSecret = decodeCrock(req.transferSecret);
+ const coinNumber = req.coinNumber;
+ // See TALER_transfer_secret_to_planchet_secret in C impl
+ const planchetMasterSecret = kdfKw({
+ ikm: transferSecret,
+ outputLength: 32,
+ salt: bufferForUint32(coinNumber),
+ info: stringToBytes("taler-coin-derivation"),
+ });
+ const coinPriv = kdfKw({
+ ikm: planchetMasterSecret,
+ outputLength: 32,
+ salt: stringToBytes("coin"),
+ });
+ const bks = kdfKw({
+ ikm: planchetMasterSecret,
+ outputLength: 32,
+ salt: stringToBytes("bks"),
+ });
+ const coinPrivEnc = encodeCrock(coinPriv);
+ const coinPubRes = await tci.eddsaGetPublic(tci, {
+ priv: coinPrivEnc,
+ });
+ return {
+ bks: encodeCrock(bks),
+ coinPriv: coinPrivEnc,
+ coinPub: coinPubRes.pub,
+ };
+ },
+ async setupWithdrawalPlanchet(tci, req) {
+ const info = stringToBytes("taler-withdrawal-coin-derivation");
+ const saltArrBuf = new ArrayBuffer(4);
+ const salt = new Uint8Array(saltArrBuf);
+ const saltDataView = new DataView(saltArrBuf);
+ saltDataView.setUint32(0, req.coinNumber);
+ const out = kdf(64, decodeCrock(req.secretSeed), salt, info);
+ const coinPriv = out.slice(0, 32);
+ const bks = out.slice(32, 64);
+ const coinPrivEnc = encodeCrock(coinPriv);
+ const coinPubRes = await tci.eddsaGetPublic(tci, {
+ priv: coinPrivEnc,
+ });
+ return {
+ bks: encodeCrock(bks),
+ coinPriv: coinPrivEnc,
+ coinPub: coinPubRes.pub,
+ };
+ },
+ async createPlanchet(tci, req) {
+ const denomPub = req.denomPub;
+ if (denomPub.cipher === DenomKeyType.Rsa) {
+ const reservePub = decodeCrock(req.reservePub);
+ const derivedPlanchet = await tci.setupWithdrawalPlanchet(tci, {
+ coinNumber: req.coinIndex,
+ secretSeed: req.secretSeed,
+ });
+ let maybeAcp = undefined;
+ let maybeAgeCommitmentHash = undefined;
+ if (denomPub.age_mask) {
+ const age = req.restrictAge || AgeRestriction.AGE_UNRESTRICTED;
+ logger$q.info(`creating age-restricted planchet (age ${age})`);
+ maybeAcp = await AgeRestriction.restrictionCommit(denomPub.age_mask, age);
+ maybeAgeCommitmentHash = AgeRestriction.hashCommitment(maybeAcp.commitment);
+ }
+ const coinPubHash = hashCoinPub(derivedPlanchet.coinPub, maybeAgeCommitmentHash);
+ const blindResp = await tci.rsaBlind(tci, {
+ bks: derivedPlanchet.bks,
+ hm: encodeCrock(coinPubHash),
+ pub: denomPub.rsa_public_key,
+ });
+ const coinEv = {
+ cipher: DenomKeyType.Rsa,
+ rsa_blinded_planchet: blindResp.blinded,
+ };
+ const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount;
+ const denomPubHash = hashDenomPub(req.denomPub);
+ const evHash = hashCoinEv(coinEv, encodeCrock(denomPubHash));
+ const withdrawRequest = buildSigPS(TalerSignaturePurpose.WALLET_RESERVE_WITHDRAW)
+ .put(amountToBuffer(amountWithFee))
+ .put(denomPubHash)
+ .put(evHash)
+ .build();
+ const sigResult = await tci.eddsaSign(tci, {
+ msg: encodeCrock(withdrawRequest),
+ priv: req.reservePriv,
+ });
+ const planchet = {
+ blindingKey: derivedPlanchet.bks,
+ coinEv,
+ coinPriv: derivedPlanchet.coinPriv,
+ coinPub: derivedPlanchet.coinPub,
+ coinValue: req.value,
+ denomPub,
+ denomPubHash: encodeCrock(denomPubHash),
+ reservePub: encodeCrock(reservePub),
+ withdrawSig: sigResult.sig,
+ coinEvHash: encodeCrock(evHash),
+ ageCommitmentProof: maybeAcp,
+ };
+ return planchet;
+ }
+ else {
+ throw Error("unsupported cipher, unable to create planchet");
+ }
+ },
+ async createTipPlanchet(tci, req) {
+ if (req.denomPub.cipher !== DenomKeyType.Rsa) {
+ throw Error(`unsupported cipher (${req.denomPub.cipher})`);
+ }
+ const fc = await setupTipPlanchet(decodeCrock(req.secretSeed), req.denomPub, req.planchetIndex);
+ const maybeAch = fc.ageCommitmentProof
+ ? AgeRestriction.hashCommitment(fc.ageCommitmentProof.commitment)
+ : undefined;
+ const denomPub = decodeCrock(req.denomPub.rsa_public_key);
+ const coinPubHash = hashCoinPub(encodeCrock(fc.coinPub), maybeAch);
+ const blindResp = await tci.rsaBlind(tci, {
+ bks: encodeCrock(fc.bks),
+ hm: encodeCrock(coinPubHash),
+ pub: encodeCrock(denomPub),
+ });
+ const coinEv = {
+ cipher: DenomKeyType.Rsa,
+ rsa_blinded_planchet: blindResp.blinded,
+ };
+ const tipPlanchet = {
+ blindingKey: encodeCrock(fc.bks),
+ coinEv,
+ coinEvHash: encodeCrock(hashCoinEv(coinEv, encodeCrock(hashDenomPub(req.denomPub)))),
+ coinPriv: encodeCrock(fc.coinPriv),
+ coinPub: encodeCrock(fc.coinPub),
+ ageCommitmentProof: fc.ageCommitmentProof,
+ };
+ return tipPlanchet;
+ },
+ async signTrackTransaction(tci, req) {
+ const p = buildSigPS(TalerSignaturePurpose.MERCHANT_TRACK_TRANSACTION)
+ .put(decodeCrock(req.contractTermsHash))
+ .put(decodeCrock(req.wireHash))
+ .put(decodeCrock(req.merchantPub))
+ .put(decodeCrock(req.coinPub))
+ .build();
+ return { sig: encodeCrock(eddsaSign(p, decodeCrock(req.merchantPriv))) };
+ },
+ /**
+ * Create and sign a message to recoup a coin.
+ */
+ async createRecoupRequest(tci, req) {
+ const p = buildSigPS(TalerSignaturePurpose.WALLET_COIN_RECOUP)
+ .put(decodeCrock(req.denomPubHash))
+ .put(decodeCrock(req.blindingKey))
+ .build();
+ const coinPriv = decodeCrock(req.coinPriv);
+ const coinSig = eddsaSign(p, coinPriv);
+ if (req.denomPub.cipher === DenomKeyType.Rsa) {
+ const paybackRequest = {
+ coin_blind_key_secret: req.blindingKey,
+ coin_sig: encodeCrock(coinSig),
+ denom_pub_hash: req.denomPubHash,
+ denom_sig: req.denomSig,
+ // FIXME!
+ ewv: {
+ cipher: "RSA",
+ },
+ };
+ return paybackRequest;
+ }
+ else {
+ throw new Error();
+ }
+ },
+ /**
+ * Create and sign a message to recoup a coin.
+ */
+ async createRecoupRefreshRequest(tci, req) {
+ const p = buildSigPS(TalerSignaturePurpose.WALLET_COIN_RECOUP_REFRESH)
+ .put(decodeCrock(req.denomPubHash))
+ .put(decodeCrock(req.blindingKey))
+ .build();
+ const coinPriv = decodeCrock(req.coinPriv);
+ const coinSig = eddsaSign(p, coinPriv);
+ if (req.denomPub.cipher === DenomKeyType.Rsa) {
+ const recoupRequest = {
+ coin_blind_key_secret: req.blindingKey,
+ coin_sig: encodeCrock(coinSig),
+ denom_pub_hash: req.denomPubHash,
+ denom_sig: req.denomSig,
+ // FIXME!
+ ewv: {
+ cipher: "RSA",
+ },
+ };
+ return recoupRequest;
+ }
+ else {
+ throw new Error();
+ }
+ },
+ /**
+ * Check if a payment signature is valid.
+ */
+ async isValidPaymentSignature(tci, req) {
+ const { contractHash, sig, merchantPub } = req;
+ const p = buildSigPS(TalerSignaturePurpose.MERCHANT_PAYMENT_OK)
+ .put(decodeCrock(contractHash))
+ .build();
+ const sigBytes = decodeCrock(sig);
+ const pubBytes = decodeCrock(merchantPub);
+ return { valid: eddsaVerify(p, sigBytes, pubBytes) };
+ },
+ /**
+ * Check if a wire fee is correctly signed.
+ */
+ async isValidWireFee(tci, req) {
+ const { type, wf, masterPub } = req;
+ const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_FEES)
+ .put(hash(stringToBytes(type + "\0")))
+ .put(timestampRoundedToBuffer(wf.startStamp))
+ .put(timestampRoundedToBuffer(wf.endStamp))
+ .put(amountToBuffer(wf.wireFee))
+ .put(amountToBuffer(wf.closingFee))
+ .build();
+ const sig = decodeCrock(wf.sig);
+ const pub = decodeCrock(masterPub);
+ return { valid: eddsaVerify(p, sig, pub) };
+ },
+ /**
+ * Check if a global fee is correctly signed.
+ */
+ async isValidGlobalFees(tci, req) {
+ const { gf, masterPub } = req;
+ const p = buildSigPS(TalerSignaturePurpose.GLOBAL_FEES)
+ .put(timestampRoundedToBuffer(gf.start_date))
+ .put(timestampRoundedToBuffer(gf.end_date))
+ .put(durationRoundedToBuffer(gf.purse_timeout))
+ .put(durationRoundedToBuffer(gf.history_expiration))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.history_fee)))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.account_fee)))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.purse_fee)))
+ .put(bufferForUint32(gf.purse_account_limit))
+ .build();
+ const sig = decodeCrock(gf.master_sig);
+ const pub = decodeCrock(masterPub);
+ return { valid: eddsaVerify(p, sig, pub) };
+ },
+ /**
+ * Check if the signature of a denomination is valid.
+ */
+ async isValidDenom(tci, req) {
+ const { masterPub, denom } = req;
+ const value = {
+ currency: denom.currency,
+ fraction: denom.amountFrac,
+ value: denom.amountVal,
+ };
+ const p = buildSigPS(TalerSignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY)
+ .put(decodeCrock(masterPub))
+ .put(timestampRoundedToBuffer(denom.stampStart))
+ .put(timestampRoundedToBuffer(denom.stampExpireWithdraw))
+ .put(timestampRoundedToBuffer(denom.stampExpireDeposit))
+ .put(timestampRoundedToBuffer(denom.stampExpireLegal))
+ .put(amountToBuffer(value))
+ .put(amountToBuffer(denom.fees.feeWithdraw))
+ .put(amountToBuffer(denom.fees.feeDeposit))
+ .put(amountToBuffer(denom.fees.feeRefresh))
+ .put(amountToBuffer(denom.fees.feeRefund))
+ .put(decodeCrock(denom.denomPubHash))
+ .build();
+ const sig = decodeCrock(denom.masterSig);
+ const pub = decodeCrock(masterPub);
+ const res = eddsaVerify(p, sig, pub);
+ return { valid: res };
+ },
+ async isValidWireAccount(tci, req) {
+ const { sig, masterPub, paytoUri } = req;
+ const paytoHash = hashTruncate32(stringToBytes(paytoUri + "\0"));
+ const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS)
+ .put(paytoHash)
+ .build();
+ return { valid: eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub)) };
+ },
+ async isValidContractTermsSignature(tci, req) {
+ const cthDec = decodeCrock(req.contractTermsHash);
+ const p = buildSigPS(TalerSignaturePurpose.MERCHANT_CONTRACT)
+ .put(cthDec)
+ .build();
+ return {
+ valid: eddsaVerify(p, decodeCrock(req.sig), decodeCrock(req.merchantPub)),
+ };
+ },
+ /**
+ * Create a new EdDSA key pair.
+ */
+ async createEddsaKeypair(tci) {
+ const eddsaPriv = encodeCrock(getRandomBytes(32));
+ const eddsaPubRes = await tci.eddsaGetPublic(tci, {
+ priv: eddsaPriv,
+ });
+ return {
+ priv: eddsaPriv,
+ pub: eddsaPubRes.pub,
+ };
+ },
+ async eddsaGetPublic(tci, req) {
+ return {
+ priv: req.priv,
+ pub: encodeCrock(eddsaGetPublic(decodeCrock(req.priv))),
+ };
+ },
+ async unblindDenominationSignature(tci, req) {
+ if (req.evSig.cipher === DenomKeyType.Rsa) {
+ if (req.planchet.denomPub.cipher !== DenomKeyType.Rsa) {
+ throw new Error("planchet cipher does not match blind signature cipher");
+ }
+ const denomSig = rsaUnblind(decodeCrock(req.evSig.blinded_rsa_signature), decodeCrock(req.planchet.denomPub.rsa_public_key), decodeCrock(req.planchet.blindingKey));
+ return {
+ cipher: DenomKeyType.Rsa,
+ rsa_signature: encodeCrock(denomSig),
+ };
+ }
+ else {
+ throw Error(`unblinding for cipher ${req.evSig.cipher} not implemented`);
+ }
+ },
+ /**
+ * Unblind a blindly signed value.
+ */
+ async rsaUnblind(tci, req) {
+ const denomSig = rsaUnblind(decodeCrock(req.blindedSig), decodeCrock(req.pk), decodeCrock(req.bk));
+ return { sig: encodeCrock(denomSig) };
+ },
+ /**
+ * Unblind a blindly signed value.
+ */
+ async rsaVerify(tci, req) {
+ return {
+ valid: rsaVerify(hash(decodeCrock(req.hm)), decodeCrock(req.sig), decodeCrock(req.pk)),
+ };
+ },
+ /**
+ * Generate updated coins (to store in the database)
+ * and deposit permissions for each given coin.
+ */
+ async signDepositPermission(tci, depositInfo) {
+ var _a;
+ // FIXME: put extensions here if used
+ const hExt = new Uint8Array(64);
+ let hAgeCommitment;
+ let minimumAgeSig = undefined;
+ if (depositInfo.ageCommitmentProof) {
+ const ach = AgeRestriction.hashCommitment(depositInfo.ageCommitmentProof.commitment);
+ hAgeCommitment = decodeCrock(ach);
+ if (depositInfo.requiredMinimumAge != null) {