summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--taler-wallet-android.js11427
1 files changed, 5726 insertions, 5701 deletions
diff --git a/taler-wallet-android.js b/taler-wallet-android.js
index bb9b4dc..b1203f4 100644
--- a/taler-wallet-android.js
+++ b/taler-wallet-android.js
@@ -14,7 +14,6 @@ var tty = _interopDefault(require('tty'));
var util = _interopDefault(require('util'));
var os = _interopDefault(require('os'));
var zlib = _interopDefault(require('zlib'));
-var querystring = _interopDefault(require('querystring'));
var fs = _interopDefault(require('fs'));
var worker_threads = _interopDefault(require('worker_threads'));
@@ -32,6 +31,244 @@ function getCjsExportFromNamespace (n) {
return n && n['default'] || n;
}
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+/* global Reflect, Promise */
+
+var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+};
+
+function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+}
+
+var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+
+function __rest(s, e) {
+ var t = {};
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
+ t[p] = s[p];
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
+ t[p[i]] = s[p[i]];
+ }
+ return t;
+}
+
+function __decorate(decorators, target, key, desc) {
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
+}
+
+function __param(paramIndex, decorator) {
+ return function (target, key) { decorator(target, key, paramIndex); }
+}
+
+function __metadata(metadataKey, metadataValue) {
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
+}
+
+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());
+ });
+}
+
+function __generator(thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+}
+
+function __exportStar(m, exports) {
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+
+function __values(o) {
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
+ if (m) return m.call(o);
+ if (o && typeof o.length === "number") return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return { value: o && o[i++], done: !o };
+ }
+ };
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
+}
+
+function __read(o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o), r, ar = [], e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ }
+ catch (error) { e = { error: error }; }
+ finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ }
+ finally { if (e) throw e.error; }
+ }
+ return ar;
+}
+
+function __spread() {
+ for (var ar = [], i = 0; i < arguments.length; i++)
+ ar = ar.concat(__read(arguments[i]));
+ return ar;
+}
+
+function __spreadArrays() {
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+ r[k] = a[j];
+ return r;
+}
+function __await(v) {
+ return this instanceof __await ? (this.v = v, this) : new __await(v);
+}
+
+function __asyncGenerator(thisArg, _arguments, generator) {
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
+ function fulfill(value) { resume("next", value); }
+ function reject(value) { resume("throw", value); }
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
+}
+
+function __asyncDelegator(o) {
+ var i, p;
+ return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
+ function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
+}
+
+function __asyncValues(o) {
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+ var m = o[Symbol.asyncIterator], i;
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
+}
+
+function __makeTemplateObject(cooked, raw) {
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
+ return cooked;
+}
+function __importStar(mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
+ result.default = mod;
+ return result;
+}
+
+function __importDefault(mod) {
+ return (mod && mod.__esModule) ? mod : { default: mod };
+}
+
+function __classPrivateFieldGet(receiver, privateMap) {
+ if (!privateMap.has(receiver)) {
+ throw new TypeError("attempted to get private field on non-instance");
+ }
+ return privateMap.get(receiver);
+}
+
+function __classPrivateFieldSet(receiver, privateMap, value) {
+ if (!privateMap.has(receiver)) {
+ throw new TypeError("attempted to set private field on non-instance");
+ }
+ privateMap.set(receiver, value);
+ return value;
+}
+
+var tslib_es6 = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ __extends: __extends,
+ get __assign () { return __assign; },
+ __rest: __rest,
+ __decorate: __decorate,
+ __param: __param,
+ __metadata: __metadata,
+ __awaiter: __awaiter,
+ __generator: __generator,
+ __exportStar: __exportStar,
+ __values: __values,
+ __read: __read,
+ __spread: __spread,
+ __spreadArrays: __spreadArrays,
+ __await: __await,
+ __asyncGenerator: __asyncGenerator,
+ __asyncDelegator: __asyncDelegator,
+ __asyncValues: __asyncValues,
+ __makeTemplateObject: __makeTemplateObject,
+ __importStar: __importStar,
+ __importDefault: __importDefault,
+ __classPrivateFieldGet: __classPrivateFieldGet,
+ __classPrivateFieldSet: __classPrivateFieldSet
+});
+
var codec = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
@@ -64,8 +301,7 @@ class DecodingError extends Error {
}
exports.DecodingError = DecodingError;
function renderContext(c) {
- var _a;
- const p = (_a = c) === null || _a === void 0 ? void 0 : _a.path;
+ const p = c === null || c === void 0 ? void 0 : c.path;
if (p) {
return p.join(".");
}
@@ -75,8 +311,8 @@ function renderContext(c) {
}
exports.renderContext = renderContext;
function joinContext(c, part) {
- var _a, _b;
- const path = (_b = (_a = c) === null || _a === void 0 ? void 0 : _a.path, (_b !== null && _b !== void 0 ? _b : []));
+ var _a;
+ const path = (_a = c === null || c === void 0 ? void 0 : c.path) !== null && _a !== void 0 ? _a : [];
return {
path: path.concat([part]),
};
@@ -293,14 +529,10 @@ function makeCodecOptional(innerCodec) {
return undefined;
}
return innerCodec.decode(x, c);
- }
+ },
};
}
exports.makeCodecOptional = makeCodecOptional;
-function typecheckedCodec(c) {
- return c;
-}
-exports.typecheckedCodec = typecheckedCodec;
});
@@ -318,7 +550,6 @@ var codec_10 = codec.codecForString;
var codec_11 = codec.codecForAny;
var codec_12 = codec.makeCodecForConstString;
var codec_13 = codec.makeCodecOptional;
-var codec_14 = codec.typecheckedCodec;
var amounts = createCommonjsModule(function (module, exports) {
/*
@@ -358,11 +589,11 @@ exports.fractionalLength = 8;
* Maximum allowed value field of an amount.
*/
exports.maxAmountValue = Math.pow(2, 52);
-exports.codecForAmountJson = () => codec.typecheckedCodec(codec.makeCodecForObject()
+exports.codecForAmountJson = () => codec.makeCodecForObject()
.property("currency", codec.codecForString)
.property("value", codec.codecForNumber)
.property("fraction", codec.codecForNumber)
- .build("AmountJson"));
+ .build("AmountJson");
/**
* Get an amount that represents zero units of a currency.
*/
@@ -531,7 +762,7 @@ function parse(s) {
if (tail.length > exports.fractionalLength + 1) {
return undefined;
}
- let value = Number.parseInt(res[2]);
+ const value = Number.parseInt(res[2]);
if (value > exports.maxAmountValue) {
return undefined;
}
@@ -570,7 +801,7 @@ exports.fromFloat = fromFloat;
* Convert to standard human-readable string representation that's
* also used in JSON formats.
*/
-function toString(a) {
+function stringify(a) {
const av = a.value + Math.floor(a.fraction / exports.fractionalBase);
const af = a.fraction % exports.fractionalBase;
let s = av.toString();
@@ -587,7 +818,7 @@ function toString(a) {
}
return `${a.currency}:${s}`;
}
-exports.toString = toString;
+exports.stringify = stringify;
/**
* Check if the argument is a valid amount in string form.
*/
@@ -603,7 +834,21 @@ function check(a) {
return false;
}
}
-exports.check = check;
+// Export all amount-related functions here for better IDE experience.
+exports.Amounts = {
+ stringify: stringify,
+ parse: parse,
+ parseOrThrow: parseOrThrow,
+ cmp: cmp,
+ add: add,
+ sum: sum,
+ sub: sub,
+ check: check,
+ getZero: getZero,
+ isZero: isZero,
+ maxAmountValue: exports.maxAmountValue,
+ fromFloat: fromFloat,
+};
});
@@ -624,7 +869,8 @@ var amounts_13 = amounts.isZero;
var amounts_14 = amounts.parse;
var amounts_15 = amounts.parseOrThrow;
var amounts_16 = amounts.fromFloat;
-var amounts_17 = amounts.check;
+var amounts_17 = amounts.stringify;
+var amounts_18 = amounts.Amounts;
var promiseUtils = createCommonjsModule(function (module, exports) {
/*
@@ -685,6 +931,8 @@ unwrapExports(promiseUtils);
var promiseUtils_1 = promiseUtils.openPromise;
var promiseUtils_2 = promiseUtils.AsyncCondition;
+var tslib_1 = getCjsExportFromNamespace(tslib_es6);
+
var query = createCommonjsModule(function (module, exports) {
/*
This file is part of TALER
@@ -701,16 +949,8 @@ var query = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Database query abstractions.
* @module Query
@@ -721,6 +961,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
*/
/**
+ * Exception that should be thrown by client code to abort a transaction.
+ */
+exports.TransactionAbort = Symbol("transaction_abort");
+/**
* Definition of an object store.
*/
class Store {
@@ -817,7 +1061,7 @@ class ResultStream {
};
}
toArray() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const arr = [];
while (true) {
const x = yield this.next();
@@ -832,7 +1076,7 @@ class ResultStream {
});
}
map(f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const arr = [];
while (true) {
const x = yield this.next();
@@ -847,7 +1091,7 @@ class ResultStream {
});
}
forEachAsync(f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
while (true) {
const x = yield this.next();
if (x.hasValue) {
@@ -860,7 +1104,7 @@ class ResultStream {
});
}
forEach(f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
while (true) {
const x = yield this.next();
if (x.hasValue) {
@@ -873,7 +1117,7 @@ class ResultStream {
});
}
filter(f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const arr = [];
while (true) {
const x = yield this.next();
@@ -890,7 +1134,7 @@ class ResultStream {
});
}
next() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.gotCursorEnd) {
return { hasValue: false };
}
@@ -941,6 +1185,13 @@ class TransactionHandle {
const req = this.tx.objectStore(store.name).openCursor(key);
return new ResultStream(req);
}
+ iterIndexed(index, key) {
+ const req = this.tx
+ .objectStore(index.storeName)
+ .index(index.indexName)
+ .openCursor(key);
+ return new ResultStream(req);
+ }
delete(store, key) {
const req = this.tx.objectStore(store.name).delete(key);
return requestToPromise(req);
@@ -954,7 +1205,7 @@ exports.TransactionHandle = TransactionHandle;
function runWithTransaction(db, stores, f, mode) {
const stack = Error("Failed transaction was started here.");
return new Promise((resolve, reject) => {
- const storeName = stores.map(x => x.name);
+ const storeName = stores.map((x) => x.name);
const tx = db.transaction(storeName, mode);
let funResult = undefined;
let gotFunResult = false;
@@ -986,21 +1237,24 @@ function runWithTransaction(db, stores, f, mode) {
reject(exports.TransactionAbort);
};
const th = new TransactionHandle(tx);
- const resP = f(th);
+ const resP = Promise.resolve().then(() => f(th));
resP
- .then(result => {
+ .then((result) => {
gotFunResult = true;
funResult = result;
})
- .catch(e => {
+ .catch((e) => {
if (e == exports.TransactionAbort) {
console.info("aborting transaction");
}
else {
- tx.abort();
console.error("Transaction failed:", e);
console.error(stack);
+ tx.abort();
}
+ })
+ .catch((e) => {
+ console.error("fatal: aborting transaction failed", e);
});
});
}
@@ -1026,11 +1280,11 @@ exports.Index = Index;
function openDatabase(idbFactory, databaseName, databaseVersion, onVersionChange, onUpgradeNeeded) {
return new Promise((resolve, reject) => {
const req = idbFactory.open(databaseName, databaseVersion);
- req.onerror = e => {
+ req.onerror = (e) => {
console.log("taler database error", e);
reject(new Error("database error"));
};
- req.onsuccess = e => {
+ req.onsuccess = (e) => {
req.result.onversionchange = (evt) => {
console.log(`handling live db version change from ${evt.oldVersion} to ${evt.newVersion}`);
req.result.close();
@@ -1038,18 +1292,18 @@ function openDatabase(idbFactory, databaseName, databaseVersion, onVersionChange
};
resolve(req.result);
};
- req.onupgradeneeded = e => {
+ req.onupgradeneeded = (e) => {
const db = req.result;
- onUpgradeNeeded(db, e.oldVersion, e.newVersion);
+ const newVersion = e.newVersion;
+ if (!newVersion) {
+ throw Error("upgrade needed, but new version unknown");
+ }
+ onUpgradeNeeded(db, e.oldVersion, newVersion);
console.log(`DB: upgrade needed: oldVersion=${e.oldVersion}, newVersion=${e.newVersion}`);
};
});
}
exports.openDatabase = openDatabase;
-/**
- * Exception that should be thrown by client code to abort a transaction.
- */
-exports.TransactionAbort = Symbol("transaction_abort");
class Database {
constructor(db) {
this.db = db;
@@ -1058,7 +1312,7 @@ class Database {
idbFactory.deleteDatabase(dbName);
}
exportDatabase() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const db = this.db;
const dump = {
name: db.name,
@@ -1113,7 +1367,7 @@ class Database {
});
}
get(store, key) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const tx = this.db.transaction([store.name], "readonly");
const req = tx.objectStore(store.name).get(key);
const v = yield requestToPromise(req);
@@ -1122,19 +1376,16 @@ class Database {
});
}
getIndexed(index, key) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const tx = this.db.transaction([index.storeName], "readonly");
- const req = tx
- .objectStore(index.storeName)
- .index(index.indexName)
- .get(key);
+ const req = tx.objectStore(index.storeName).index(index.indexName).get(key);
const v = yield requestToPromise(req);
yield transactionToPromise(tx);
return v;
});
}
put(store, value, key) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const tx = this.db.transaction([store.name], "readwrite");
const req = tx.objectStore(store.name).put(value, key);
const v = yield requestToPromise(req);
@@ -1143,7 +1394,7 @@ class Database {
});
}
mutate(store, key, f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const tx = this.db.transaction([store.name], "readwrite");
const req = tx.objectStore(store.name).openCursor(key);
yield applyMutation(req, f);
@@ -1164,12 +1415,12 @@ class Database {
return new ResultStream(req);
}
runWithReadTransaction(stores, f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return runWithTransaction(this.db, stores, f, "readonly");
});
}
runWithWriteTransaction(stores, f) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return runWithTransaction(this.db, stores, f, "readwrite");
});
}
@@ -1179,11 +1430,11 @@ exports.Database = Database;
});
unwrapExports(query);
-var query_1 = query.Store;
-var query_2 = query.TransactionHandle;
-var query_3 = query.Index;
-var query_4 = query.openDatabase;
-var query_5 = query.TransactionAbort;
+var query_1 = query.TransactionAbort;
+var query_2 = query.Store;
+var query_3 = query.TransactionHandle;
+var query_4 = query.Index;
+var query_5 = query.openDatabase;
var query_6 = query.Database;
var time = createCommonjsModule(function (module, exports) {
@@ -1210,9 +1461,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
class Timestamp {
}
exports.Timestamp = Timestamp;
+let timeshift = 0;
+function setDangerousTimetravel(dt) {
+ timeshift = dt;
+}
+exports.setDangerousTimetravel = setDangerousTimetravel;
function getTimestampNow() {
return {
- t_ms: new Date().getTime(),
+ t_ms: new Date().getTime() + timeshift,
};
}
exports.getTimestampNow = getTimestampNow;
@@ -1239,6 +1495,19 @@ function timestampMin(t1, t2) {
return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
}
exports.timestampMin = timestampMin;
+/**
+ * Truncate a timestamp so that that it represents a multiple
+ * of seconds. The timestamp is always rounded down.
+ */
+function timestampTruncateToSecond(t1) {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ return {
+ t_ms: Math.floor(t1.t_ms / 1000) * 1000,
+ };
+}
+exports.timestampTruncateToSecond = timestampTruncateToSecond;
function durationMin(d1, d2) {
if (d1.d_ms === "forever") {
return { d_ms: d2.d_ms };
@@ -1302,6 +1571,16 @@ function timestampDifference(t1, t2) {
return { d_ms: Math.abs(t1.t_ms - t2.t_ms) };
}
exports.timestampDifference = timestampDifference;
+function timestampIsBetween(t, start, end) {
+ if (timestampCmp(t, start) < 0) {
+ return false;
+ }
+ if (timestampCmp(t, end) > 0) {
+ return false;
+ }
+ return true;
+}
+exports.timestampIsBetween = timestampIsBetween;
exports.codecForTimestamp = {
decode(x, c) {
const t_ms = x.t_ms;
@@ -1337,17 +1616,20 @@ exports.codecForDuration = {
unwrapExports(time);
var time_1 = time.Timestamp;
-var time_2 = time.getTimestampNow;
-var time_3 = time.getDurationRemaining;
-var time_4 = time.timestampMin;
-var time_5 = time.durationMin;
-var time_6 = time.timestampCmp;
-var time_7 = time.timestampAddDuration;
-var time_8 = time.timestampSubtractDuraction;
-var time_9 = time.stringifyTimestamp;
-var time_10 = time.timestampDifference;
-var time_11 = time.codecForTimestamp;
-var time_12 = time.codecForDuration;
+var time_2 = time.setDangerousTimetravel;
+var time_3 = time.getTimestampNow;
+var time_4 = time.getDurationRemaining;
+var time_5 = time.timestampMin;
+var time_6 = time.timestampTruncateToSecond;
+var time_7 = time.durationMin;
+var time_8 = time.timestampCmp;
+var time_9 = time.timestampAddDuration;
+var time_10 = time.timestampSubtractDuraction;
+var time_11 = time.stringifyTimestamp;
+var time_12 = time.timestampDifference;
+var time_13 = time.timestampIsBetween;
+var time_14 = time.codecForTimestamp;
+var time_15 = time.codecForDuration;
var dbTypes = createCommonjsModule(function (module, exports) {
/*
@@ -1455,26 +1737,6 @@ var DenominationStatus;
DenominationStatus[DenominationStatus["VerifiedBad"] = 2] = "VerifiedBad";
})(DenominationStatus = exports.DenominationStatus || (exports.DenominationStatus = {}));
/**
- * Status of a coin.
- */
-var CoinStatus;
-(function (CoinStatus) {
- /**
- * Withdrawn and never shown to anybody.
- */
- CoinStatus["Fresh"] = "fresh";
- /**
- * A coin that has been spent and refreshed.
- */
- CoinStatus["Dormant"] = "dormant";
-})(CoinStatus = exports.CoinStatus || (exports.CoinStatus = {}));
-var CoinSource;
-(function (CoinSource) {
- CoinSource["Withdraw"] = "withdraw";
- CoinSource["Refresh"] = "refresh";
- CoinSource["Tip"] = "tip";
-})(CoinSource = exports.CoinSource || (exports.CoinSource = {}));
-/**
* Record to keep track of data imported into the wallet.
*/
class WalletImportRecord {
@@ -1484,6 +1746,7 @@ exports.WalletImportRecord = WalletImportRecord;
/**
* The stores and indices for the wallet database.
*/
+// eslint-disable-next-line @typescript-eslint/no-namespace
var Stores;
(function (Stores) {
class ExchangesStore extends query.Store {
@@ -1496,7 +1759,7 @@ var Stores;
super("coins", { keyPath: "coinPub" });
this.exchangeBaseUrlIndex = new query.Index(this, "exchangeBaseUrl", "exchangeBaseUrl");
this.denomPubIndex = new query.Index(this, "denomPubIndex", "denomPub");
- this.byWithdrawalWithIdx = new query.Index(this, "planchetsByWithdrawalWithIdxIndex", ["withdrawSessionId", "coinIndex"]);
+ this.denomPubHashIndex = new query.Index(this, "denomPubHashIndex", "denomPubHash");
}
}
class ProposalsStore extends query.Store {
@@ -1554,9 +1817,9 @@ var Stores;
super("senderWires", { keyPath: "paytoUri" });
}
}
- class WithdrawalSessionsStore extends query.Store {
+ class WithdrawalGroupsStore extends query.Store {
constructor() {
- super("withdrawals", { keyPath: "withdrawSessionId" });
+ super("withdrawals", { keyPath: "withdrawalGroupId" });
}
}
class RefundEventsStore extends query.Store {
@@ -1601,11 +1864,14 @@ var Stores;
Stores.refreshGroups = new query.Store("refreshGroups", {
keyPath: "refreshGroupId",
});
+ Stores.recoupGroups = new query.Store("recoupGroups", {
+ keyPath: "recoupGroupId",
+ });
Stores.reserves = new ReservesStore();
Stores.purchases = new PurchasesStore();
Stores.tips = new TipsStore();
Stores.senderWires = new SenderWiresStore();
- Stores.withdrawalSession = new WithdrawalSessionsStore();
+ Stores.withdrawalGroups = new WithdrawalGroupsStore();
Stores.bankWithdrawUris = new BankWithdrawUrisStore();
Stores.refundEvents = new RefundEventsStore();
Stores.payEvents = new PayEventsStore();
@@ -1622,10 +1888,8 @@ var dbTypes_1 = dbTypes.ReserveRecordStatus;
var dbTypes_2 = dbTypes.updateRetryInfoTimeout;
var dbTypes_3 = dbTypes.initRetryInfo;
var dbTypes_4 = dbTypes.DenominationStatus;
-var dbTypes_5 = dbTypes.CoinStatus;
-var dbTypes_6 = dbTypes.CoinSource;
-var dbTypes_7 = dbTypes.WalletImportRecord;
-var dbTypes_8 = dbTypes.Stores;
+var dbTypes_5 = dbTypes.WalletImportRecord;
+var dbTypes_6 = dbTypes.Stores;
var talerTypes = createCommonjsModule(function (module, exports) {
/*
@@ -1727,9 +1991,15 @@ exports.TipResponse = TipResponse;
* Element of the payback list that the
* exchange gives us in /keys.
*/
-class Payback {
+class Recoup {
}
-exports.Payback = Payback;
+exports.Recoup = Recoup;
+/**
+ * Structure of one exchange signing key in the /keys response.
+ */
+class ExchangeSignKeyJson {
+}
+exports.ExchangeSignKeyJson = ExchangeSignKeyJson;
/**
* Structure that the exchange gives us in /keys.
*/
@@ -1772,7 +2042,10 @@ exports.WithdrawOperationStatusResponse = WithdrawOperationStatusResponse;
class TipPickupGetResponse {
}
exports.TipPickupGetResponse = TipPickupGetResponse;
-exports.codecForDenomination = () => codec.typecheckedCodec(codec.makeCodecForObject()
+class WithdrawResponse {
+}
+exports.WithdrawResponse = WithdrawResponse;
+exports.codecForDenomination = () => codec.makeCodecForObject()
.property("value", codec.codecForString)
.property("denom_pub", codec.codecForString)
.property("fee_withdraw", codec.codecForString)
@@ -1784,26 +2057,26 @@ exports.codecForDenomination = () => codec.typecheckedCodec(codec.makeCodecForOb
.property("stamp_expire_legal", time.codecForTimestamp)
.property("stamp_expire_deposit", time.codecForTimestamp)
.property("master_sig", codec.codecForString)
- .build("Denomination"));
-exports.codecForAuditorDenomSig = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("Denomination");
+exports.codecForAuditorDenomSig = () => codec.makeCodecForObject()
.property("denom_pub_h", codec.codecForString)
.property("auditor_sig", codec.codecForString)
- .build("AuditorDenomSig"));
-exports.codecForAuditor = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("AuditorDenomSig");
+exports.codecForAuditor = () => codec.makeCodecForObject()
.property("auditor_pub", codec.codecForString)
.property("auditor_url", codec.codecForString)
.property("denomination_keys", codec.makeCodecForList(exports.codecForAuditorDenomSig()))
- .build("Auditor"));
-exports.codecForExchangeHandle = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("Auditor");
+exports.codecForExchangeHandle = () => codec.makeCodecForObject()
.property("master_pub", codec.codecForString)
.property("url", codec.codecForString)
- .build("ExchangeHandle"));
-exports.codecForAuditorHandle = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("ExchangeHandle");
+exports.codecForAuditorHandle = () => codec.makeCodecForObject()
.property("name", codec.codecForString)
.property("master_pub", codec.codecForString)
.property("url", codec.codecForString)
- .build("AuditorHandle"));
-exports.codecForContractTerms = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("AuditorHandle");
+exports.codecForContractTerms = () => codec.makeCodecForObject()
.property("order_id", codec.codecForString)
.property("fulfillment_url", codec.codecForString)
.property("merchant_base_url", codec.codecForString)
@@ -1826,66 +2099,73 @@ exports.codecForContractTerms = () => codec.typecheckedCodec(codec.makeCodecForO
.property("exchanges", codec.makeCodecForList(exports.codecForExchangeHandle()))
.property("products", codec.makeCodecOptional(codec.makeCodecForList(codec.codecForAny)))
.property("extra", codec.codecForAny)
- .build("ContractTerms"));
-exports.codecForMerchantRefundPermission = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("ContractTerms");
+exports.codecForMerchantRefundPermission = () => codec.makeCodecForObject()
.property("refund_amount", codec.codecForString)
.property("refund_fee", codec.codecForString)
.property("coin_pub", codec.codecForString)
.property("rtransaction_id", codec.codecForNumber)
.property("merchant_sig", codec.codecForString)
- .build("MerchantRefundPermission"));
-exports.codecForMerchantRefundResponse = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("MerchantRefundPermission");
+exports.codecForMerchantRefundResponse = () => codec.makeCodecForObject()
.property("merchant_pub", codec.codecForString)
.property("h_contract_terms", codec.codecForString)
.property("refund_permissions", codec.makeCodecForList(exports.codecForMerchantRefundPermission()))
- .build("MerchantRefundResponse"));
-exports.codecForReserveSigSingleton = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("MerchantRefundResponse");
+exports.codecForReserveSigSingleton = () => codec.makeCodecForObject()
.property("reserve_sig", codec.codecForString)
- .build("ReserveSigSingleton"));
-exports.codecForTipResponse = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("ReserveSigSingleton");
+exports.codecForTipResponse = () => codec.makeCodecForObject()
.property("reserve_pub", codec.codecForString)
.property("reserve_sigs", codec.makeCodecForList(exports.codecForReserveSigSingleton()))
- .build("TipResponse"));
-exports.codecForPayback = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("TipResponse");
+exports.codecForRecoup = () => codec.makeCodecForObject()
.property("h_denom_pub", codec.codecForString)
- .build("Payback"));
-exports.codecForExchangeKeysJson = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("Recoup");
+exports.codecForExchangeSigningKey = () => codec.makeCodecForObject()
+ .property("key", codec.codecForString)
+ .property("master_sig", codec.codecForString)
+ .property("stamp_end", time.codecForTimestamp)
+ .property("stamp_start", time.codecForTimestamp)
+ .property("stamp_expire", time.codecForTimestamp)
+ .build("ExchangeSignKeyJson");
+exports.codecForExchangeKeysJson = () => codec.makeCodecForObject()
.property("denoms", codec.makeCodecForList(exports.codecForDenomination()))
.property("master_public_key", codec.codecForString)
.property("auditors", codec.makeCodecForList(exports.codecForAuditor()))
.property("list_issue_date", time.codecForTimestamp)
- .property("payback", codec.makeCodecOptional(codec.makeCodecForList(exports.codecForPayback())))
- .property("signkeys", codec.codecForAny)
+ .property("recoup", codec.makeCodecOptional(codec.makeCodecForList(exports.codecForRecoup())))
+ .property("signkeys", codec.makeCodecForList(exports.codecForExchangeSigningKey()))
.property("version", codec.codecForString)
- .build("KeysJson"));
-exports.codecForWireFeesJson = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("KeysJson");
+exports.codecForWireFeesJson = () => codec.makeCodecForObject()
.property("wire_fee", codec.codecForString)
.property("closing_fee", codec.codecForString)
.property("sig", codec.codecForString)
.property("start_date", time.codecForTimestamp)
.property("end_date", time.codecForTimestamp)
- .build("WireFeesJson"));
-exports.codecForAccountInfo = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("WireFeesJson");
+exports.codecForAccountInfo = () => codec.makeCodecForObject()
.property("payto_uri", codec.codecForString)
.property("master_sig", codec.codecForString)
- .build("AccountInfo"));
-exports.codecForExchangeWireJson = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("AccountInfo");
+exports.codecForExchangeWireJson = () => codec.makeCodecForObject()
.property("accounts", codec.makeCodecForList(exports.codecForAccountInfo()))
.property("fees", codec.makeCodecForMap(codec.makeCodecForList(exports.codecForWireFeesJson())))
- .build("ExchangeWireJson"));
-exports.codecForProposal = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("ExchangeWireJson");
+exports.codecForProposal = () => codec.makeCodecForObject()
.property("contract_terms", codec.codecForAny)
.property("sig", codec.codecForString)
- .build("Proposal"));
-exports.codecForCheckPaymentResponse = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("Proposal");
+exports.codecForCheckPaymentResponse = () => codec.makeCodecForObject()
.property("paid", codec.codecForBoolean)
.property("refunded", codec.makeCodecOptional(codec.codecForBoolean))
.property("refunded_amount", codec.makeCodecOptional(codec.codecForString))
.property("contract_terms", codec.makeCodecOptional(codec.codecForAny))
.property("taler_pay_uri", codec.makeCodecOptional(codec.codecForString))
.property("contract_url", codec.makeCodecOptional(codec.codecForString))
- .build("CheckPaymentResponse"));
-exports.codecForWithdrawOperationStatusResponse = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("CheckPaymentResponse");
+exports.codecForWithdrawOperationStatusResponse = () => codec.makeCodecForObject()
.property("selection_done", codec.codecForBoolean)
.property("transfer_done", codec.codecForBoolean)
.property("amount", codec.codecForString)
@@ -1893,22 +2173,22 @@ exports.codecForWithdrawOperationStatusResponse = () => codec.typecheckedCodec(c
.property("suggested_exchange", codec.makeCodecOptional(codec.codecForString))
.property("confirm_transfer_url", codec.makeCodecOptional(codec.codecForString))
.property("wire_types", codec.makeCodecForList(codec.codecForString))
- .build("WithdrawOperationStatusResponse"));
-exports.codecForTipPickupGetResponse = () => codec.typecheckedCodec(codec.makeCodecForObject()
+ .build("WithdrawOperationStatusResponse");
+exports.codecForTipPickupGetResponse = () => codec.makeCodecForObject()
.property("extra", codec.codecForAny)
.property("amount", codec.codecForString)
.property("amount_left", codec.codecForString)
.property("exchange_url", codec.codecForString)
.property("stamp_expire", time.codecForTimestamp)
.property("stamp_created", time.codecForTimestamp)
- .build("TipPickupGetResponse"));
-exports.codecForRecoupConfirmation = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("reserve_pub", codec.codecForString)
- .property("amount", codec.codecForString)
- .property("timestamp", time.codecForTimestamp)
- .property("exchange_sig", codec.codecForString)
- .property("exchange_pub", codec.codecForString)
- .build("RecoupConfirmation"));
+ .build("TipPickupGetResponse");
+exports.codecForRecoupConfirmation = () => codec.makeCodecForObject()
+ .property("reserve_pub", codec.makeCodecOptional(codec.codecForString))
+ .property("old_coin_pub", codec.makeCodecOptional(codec.codecForString))
+ .build("RecoupConfirmation");
+exports.codecForWithdrawResponse = () => codec.makeCodecForObject()
+ .property("ev_sig", codec.codecForString)
+ .build("WithdrawResponse");
});
@@ -1924,35 +2204,39 @@ var talerTypes_8 = talerTypes.MerchantRefundPermission;
var talerTypes_9 = talerTypes.MerchantRefundResponse;
var talerTypes_10 = talerTypes.ReserveSigSingleton;
var talerTypes_11 = talerTypes.TipResponse;
-var talerTypes_12 = talerTypes.Payback;
-var talerTypes_13 = talerTypes.ExchangeKeysJson;
-var talerTypes_14 = talerTypes.WireFeesJson;
-var talerTypes_15 = talerTypes.AccountInfo;
-var talerTypes_16 = talerTypes.ExchangeWireJson;
-var talerTypes_17 = talerTypes.Proposal;
-var talerTypes_18 = talerTypes.CheckPaymentResponse;
-var talerTypes_19 = talerTypes.WithdrawOperationStatusResponse;
-var talerTypes_20 = talerTypes.TipPickupGetResponse;
-var talerTypes_21 = talerTypes.codecForDenomination;
-var talerTypes_22 = talerTypes.codecForAuditorDenomSig;
-var talerTypes_23 = talerTypes.codecForAuditor;
-var talerTypes_24 = talerTypes.codecForExchangeHandle;
-var talerTypes_25 = talerTypes.codecForAuditorHandle;
-var talerTypes_26 = talerTypes.codecForContractTerms;
-var talerTypes_27 = talerTypes.codecForMerchantRefundPermission;
-var talerTypes_28 = talerTypes.codecForMerchantRefundResponse;
-var talerTypes_29 = talerTypes.codecForReserveSigSingleton;
-var talerTypes_30 = talerTypes.codecForTipResponse;
-var talerTypes_31 = talerTypes.codecForPayback;
-var talerTypes_32 = talerTypes.codecForExchangeKeysJson;
-var talerTypes_33 = talerTypes.codecForWireFeesJson;
-var talerTypes_34 = talerTypes.codecForAccountInfo;
-var talerTypes_35 = talerTypes.codecForExchangeWireJson;
-var talerTypes_36 = talerTypes.codecForProposal;
-var talerTypes_37 = talerTypes.codecForCheckPaymentResponse;
-var talerTypes_38 = talerTypes.codecForWithdrawOperationStatusResponse;
-var talerTypes_39 = talerTypes.codecForTipPickupGetResponse;
-var talerTypes_40 = talerTypes.codecForRecoupConfirmation;
+var talerTypes_12 = talerTypes.Recoup;
+var talerTypes_13 = talerTypes.ExchangeSignKeyJson;
+var talerTypes_14 = talerTypes.ExchangeKeysJson;
+var talerTypes_15 = talerTypes.WireFeesJson;
+var talerTypes_16 = talerTypes.AccountInfo;
+var talerTypes_17 = talerTypes.ExchangeWireJson;
+var talerTypes_18 = talerTypes.Proposal;
+var talerTypes_19 = talerTypes.CheckPaymentResponse;
+var talerTypes_20 = talerTypes.WithdrawOperationStatusResponse;
+var talerTypes_21 = talerTypes.TipPickupGetResponse;
+var talerTypes_22 = talerTypes.WithdrawResponse;
+var talerTypes_23 = talerTypes.codecForDenomination;
+var talerTypes_24 = talerTypes.codecForAuditorDenomSig;
+var talerTypes_25 = talerTypes.codecForAuditor;
+var talerTypes_26 = talerTypes.codecForExchangeHandle;
+var talerTypes_27 = talerTypes.codecForAuditorHandle;
+var talerTypes_28 = talerTypes.codecForContractTerms;
+var talerTypes_29 = talerTypes.codecForMerchantRefundPermission;
+var talerTypes_30 = talerTypes.codecForMerchantRefundResponse;
+var talerTypes_31 = talerTypes.codecForReserveSigSingleton;
+var talerTypes_32 = talerTypes.codecForTipResponse;
+var talerTypes_33 = talerTypes.codecForRecoup;
+var talerTypes_34 = talerTypes.codecForExchangeSigningKey;
+var talerTypes_35 = talerTypes.codecForExchangeKeysJson;
+var talerTypes_36 = talerTypes.codecForWireFeesJson;
+var talerTypes_37 = talerTypes.codecForAccountInfo;
+var talerTypes_38 = talerTypes.codecForExchangeWireJson;
+var talerTypes_39 = talerTypes.codecForProposal;
+var talerTypes_40 = talerTypes.codecForCheckPaymentResponse;
+var talerTypes_41 = talerTypes.codecForWithdrawOperationStatusResponse;
+var talerTypes_42 = talerTypes.codecForTipPickupGetResponse;
+var talerTypes_43 = talerTypes.codecForRecoupConfirmation;
+var talerTypes_44 = talerTypes.codecForWithdrawResponse;
var taleruri = createCommonjsModule(function (module, exports) {
/*
@@ -2149,6 +2433,49 @@ var taleruri_4 = taleruri.parsePayUri;
var taleruri_5 = taleruri.parseTipUri;
var taleruri_6 = taleruri.parseRefundUri;
+var compat = createCommonjsModule(function (module, exports) {
+/*
+ This file is part of TALER
+ (C) 2017 INRIA
+
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Compatibility helpers needed for browsers that don't implement
+ * WebExtension APIs consistently.
+ */
+function isFirefox() {
+ const rt = chrome.runtime;
+ if (typeof rt.getBrowserInfo === "function") {
+ return true;
+ }
+ return false;
+}
+exports.isFirefox = isFirefox;
+/**
+ * Check if we are running under nodejs.
+ */
+function isNode() {
+ return typeof process !== "undefined" && process.release.name === "node";
+}
+exports.isNode = isNode;
+
+});
+
+unwrapExports(compat);
+var compat_1 = compat.isFirefox;
+var compat_2 = compat.isNode;
+
var logging = createCommonjsModule(function (module, exports) {
/*
This file is part of TALER
@@ -2166,15 +2493,58 @@ var logging = createCommonjsModule(function (module, exports) {
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Imports.
+ */
+
+function writeNodeLog(message, tag, level, args) {
+ process.stderr.write(`${new Date().toISOString()} ${tag} ${level} `);
+ process.stderr.write(message);
+ if (args.length != 0) {
+ process.stderr.write(" ");
+ process.stderr.write(JSON.stringify(args, undefined, 2));
+ }
+ process.stderr.write("\n");
+}
+/**
+ * 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;
}
info(message, ...args) {
- console.log(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
+ if (compat.isNode()) {
+ writeNodeLog(message, this.tag, "INFO", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
+ }
+ }
+ warn(message, ...args) {
+ if (compat.isNode()) {
+ writeNodeLog(message, this.tag, "WARN", args);
+ }
+ else {
+ console.warn(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args);
+ }
+ }
+ error(message, ...args) {
+ if (compat.isNode()) {
+ writeNodeLog(message, this.tag, "ERROR", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} ERROR ` + message, ...args);
+ }
}
trace(message, ...args) {
- console.log(`${new Date().toISOString()} ${this.tag} TRACE ` + message, ...args);
+ if (compat.isNode()) {
+ writeNodeLog(message, this.tag, "TRACE", args);
+ }
+ else {
+ console.info(`${new Date().toISOString()} ${this.tag} TRACE ` + message, ...args);
+ }
}
}
exports.Logger = Logger;
@@ -2200,15 +2570,9 @@ var helpers = createCommonjsModule(function (module, exports) {
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 __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+const Amounts = tslib_1.__importStar(amounts);
/**
* Show an amount in a form suitable for the user.
* FIXME: In the future, this should consider currency-specific
@@ -2279,10 +2643,15 @@ function deepEquals(x, y) {
return false;
}
const p = Object.keys(x);
- return Object.keys(y).every((i) => p.indexOf(i) !== -1) &&
- p.every((i) => deepEquals(x[i], y[i]));
+ return (Object.keys(y).every((i) => p.indexOf(i) !== -1) &&
+ p.every((i) => deepEquals(x[i], y[i])));
}
exports.deepEquals = deepEquals;
+function deepCopy(x) {
+ // FIXME: this has many issues ...
+ return JSON.parse(JSON.stringify(x));
+}
+exports.deepCopy = deepCopy;
/**
* Map from a collection to a list or results and then
* concatenate the results.
@@ -2303,8 +2672,8 @@ function hash(val) {
h = (h * 33) ^ str.charCodeAt(--i);
}
/* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
- * integers. Since we want the results to be always positive, convert the
- * signed int to an unsigned by doing an unsigned bitshift. */
+ * integers. Since we want the results to be always positive, convert the
+ * signed int to an unsigned by doing an unsigned bitshift. */
return h >>> 0;
}
exports.hash = hash;
@@ -2321,16 +2690,6 @@ function strcmp(s1, s2) {
return 0;
}
exports.strcmp = strcmp;
-/**
- * Run a function and return its result.
- *
- * Used as a nicer-looking way to do immediately invoked function
- * expressions (IFFEs).
- */
-function runBlock(f) {
- return f();
-}
-exports.runBlock = runBlock;
});
@@ -2339,10 +2698,10 @@ var helpers_1 = helpers.amountToPretty;
var helpers_2 = helpers.canonicalizeBaseUrl;
var helpers_3 = helpers.canonicalJson;
var helpers_4 = helpers.deepEquals;
-var helpers_5 = helpers.flatMap;
-var helpers_6 = helpers.hash;
-var helpers_7 = helpers.strcmp;
-var helpers_8 = helpers.runBlock;
+var helpers_5 = helpers.deepCopy;
+var helpers_6 = helpers.flatMap;
+var helpers_7 = helpers.hash;
+var helpers_8 = helpers.strcmp;
var payto = createCommonjsModule(function (module, exports) {
/*
@@ -2392,19 +2751,9 @@ unwrapExports(payto);
var payto_1 = payto.parsePaytoUri;
var errors = createCommonjsModule(function (module, exports) {
-var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-Object.defineProperty(exports, "__esModule", { value: true });
/*
This file is part of GNU Taler
- (C) 2019 GNUnet e.V.
+ (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
@@ -2417,13 +2766,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
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/>
*/
+Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* This exception is there to let the caller know that an error happened,
* but the error has already been reported by writing it to the database.
*/
class OperationFailedAndReportedError extends Error {
- constructor(message) {
- super(message);
+ constructor(operationError) {
+ super(operationError.message);
+ this.operationError = operationError;
// Set the prototype explicitly.
Object.setPrototypeOf(this, OperationFailedAndReportedError.prototype);
}
@@ -2434,21 +2786,78 @@ exports.OperationFailedAndReportedError = OperationFailedAndReportedError;
* responsible for recording the failure in the database.
*/
class OperationFailedError extends Error {
- constructor(message, err) {
- super(message);
- this.err = err;
+ constructor(operationError) {
+ super(operationError.message);
+ this.operationError = operationError;
// Set the prototype explicitly.
Object.setPrototypeOf(this, OperationFailedError.prototype);
}
}
exports.OperationFailedError = OperationFailedError;
/**
+ * Process an HTTP response that we expect to contain Taler-specific JSON.
+ *
+ * Depending on the status code, we throw an exception. This function
+ * will try to extract Taler-specific error information from the HTTP response
+ * if possible.
+ */
+function scrutinizeTalerJsonResponse(resp, codec) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ // FIXME: We should distinguish between different types of error status
+ // to react differently (throttle, report permanent failure)
+ // FIXME: Make sure that when we receive an error message,
+ // it looks like a Taler error message
+ if (resp.status !== 200) {
+ let exc = undefined;
+ try {
+ const errorJson = yield resp.json();
+ const m = `received error response (status ${resp.status})`;
+ exc = new OperationFailedError({
+ type: "protocol",
+ message: m,
+ details: {
+ httpStatusCode: resp.status,
+ errorResponse: errorJson,
+ },
+ });
+ }
+ catch (e) {
+ const m = "could not parse response JSON";
+ exc = new OperationFailedError({
+ type: "network",
+ message: m,
+ details: {
+ status: resp.status,
+ },
+ });
+ }
+ throw exc;
+ }
+ let json;
+ try {
+ json = yield resp.json();
+ }
+ catch (e) {
+ const m = "could not parse response JSON";
+ throw new OperationFailedError({
+ type: "network",
+ message: m,
+ details: {
+ status: resp.status,
+ },
+ });
+ }
+ return codec.decode(json);
+ });
+}
+exports.scrutinizeTalerJsonResponse = scrutinizeTalerJsonResponse;
+/**
* Run an operation and call the onOpError callback
* when there was an exception or operation error that must be reported.
* The cause will be re-thrown to the caller.
*/
function guardOperationException(op, onOpError) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return yield op();
}
@@ -2458,27 +2867,29 @@ function guardOperationException(op, onOpError) {
throw e;
}
if (e instanceof OperationFailedError) {
- yield onOpError(e.err);
- throw new OperationFailedAndReportedError(e.message);
+ yield onOpError(e.operationError);
+ throw new OperationFailedAndReportedError(e.operationError);
}
if (e instanceof Error) {
console.log("guard: caught Error");
- yield onOpError({
+ const opErr = {
type: "exception",
message: e.message,
details: {},
- });
- throw new OperationFailedAndReportedError(e.message);
+ };
+ yield onOpError(opErr);
+ throw new OperationFailedAndReportedError(opErr);
}
console.log("guard: caught something else");
- yield onOpError({
+ const opErr = {
type: "exception",
message: "non-error exception thrown",
details: {
value: e.toString(),
},
- });
- throw new OperationFailedAndReportedError(e.message);
+ };
+ yield onOpError(opErr);
+ throw new OperationFailedAndReportedError(opErr);
}
});
}
@@ -2489,7 +2900,8 @@ exports.guardOperationException = guardOperationException;
unwrapExports(errors);
var errors_1 = errors.OperationFailedAndReportedError;
var errors_2 = errors.OperationFailedError;
-var errors_3 = errors.guardOperationException;
+var errors_3 = errors.scrutinizeTalerJsonResponse;
+var errors_4 = errors.guardOperationException;
var versions = createCommonjsModule(function (module, exports) {
/*
@@ -2514,7 +2926,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
*
* Uses libtool's current:revision:age versioning.
*/
-exports.WALLET_EXCHANGE_PROTOCOL_VERSION = "6";
+exports.WALLET_EXCHANGE_PROTOCOL_VERSION = "7:0:0";
/**
* Cache breaker that is appended to queries such as /keys and /wire
* to break through caching, if it has been accidentally/badly configured
@@ -2530,470 +2942,6 @@ unwrapExports(versions);
var versions_1 = versions.WALLET_EXCHANGE_PROTOCOL_VERSION;
var versions_2 = versions.WALLET_CACHE_BREAKER_CLIENT_VERSION;
-var exchanges = createCommonjsModule(function (module, exports) {
-/*
- 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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-
-
-
-const Amounts = __importStar(amounts);
-
-
-
-
-function denominationRecordFromKeys(ws, exchangeBaseUrl, denomIn) {
- return __awaiter(this, void 0, void 0, function* () {
- const denomPubHash = yield ws.cryptoApi.hashDenomPub(denomIn.denom_pub);
- const d = {
- denomPub: denomIn.denom_pub,
- denomPubHash,
- exchangeBaseUrl,
- feeDeposit: Amounts.parseOrThrow(denomIn.fee_deposit),
- feeRefresh: Amounts.parseOrThrow(denomIn.fee_refresh),
- feeRefund: Amounts.parseOrThrow(denomIn.fee_refund),
- feeWithdraw: Amounts.parseOrThrow(denomIn.fee_withdraw),
- isOffered: true,
- masterSig: denomIn.master_sig,
- stampExpireDeposit: denomIn.stamp_expire_deposit,
- stampExpireLegal: denomIn.stamp_expire_legal,
- stampExpireWithdraw: denomIn.stamp_expire_withdraw,
- stampStart: denomIn.stamp_start,
- status: dbTypes.DenominationStatus.Unverified,
- value: Amounts.parseOrThrow(denomIn.value),
- };
- return d;
- });
-}
-function setExchangeError(ws, baseUrl, err) {
- return __awaiter(this, void 0, void 0, function* () {
- const mut = (exchange) => {
- exchange.lastError = err;
- return exchange;
- };
- yield ws.db.mutate(dbTypes.Stores.exchanges, baseUrl, mut);
- });
-}
-/**
- * Fetch the exchange's /keys and update our database accordingly.
- *
- * Exceptions thrown in this method must be caught and reported
- * in the pending operations.
- */
-function updateExchangeWithKeys(ws, baseUrl) {
- var _a, _b;
- return __awaiter(this, void 0, void 0, function* () {
- const existingExchangeRecord = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
- if (((_a = existingExchangeRecord) === null || _a === void 0 ? void 0 : _a.updateStatus) != "fetch-keys" /* FetchKeys */) {
- return;
- }
- const keysUrl = new URL("keys", baseUrl);
- keysUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
- let keysResp;
- try {
- const r = yield ws.http.get(keysUrl.href);
- if (r.status !== 200) {
- throw Error(`unexpected status for keys: ${r.status}`);
- }
- keysResp = yield r.json();
- }
- catch (e) {
- const m = `Fetching keys failed: ${e.message}`;
- yield setExchangeError(ws, baseUrl, {
- type: "network",
- details: {
- requestUrl: (_b = e.config) === null || _b === void 0 ? void 0 : _b.url,
- },
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- let exchangeKeysJson;
- try {
- exchangeKeysJson = talerTypes.codecForExchangeKeysJson().decode(keysResp);
- }
- catch (e) {
- const m = `Parsing /keys response failed: ${e.message}`;
- yield setExchangeError(ws, baseUrl, {
- type: "protocol-violation",
- details: {},
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- const lastUpdateTimestamp = exchangeKeysJson.list_issue_date;
- if (!lastUpdateTimestamp) {
- const m = `Parsing /keys response failed: invalid list_issue_date.`;
- yield setExchangeError(ws, baseUrl, {
- type: "protocol-violation",
- details: {},
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- if (exchangeKeysJson.denoms.length === 0) {
- const m = "exchange doesn't offer any denominations";
- yield setExchangeError(ws, baseUrl, {
- type: "protocol-violation",
- details: {},
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- const protocolVersion = exchangeKeysJson.version;
- if (!protocolVersion) {
- const m = "outdate exchange, no version in /keys response";
- yield setExchangeError(ws, baseUrl, {
- type: "protocol-violation",
- details: {},
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- const currency = Amounts.parseOrThrow(exchangeKeysJson.denoms[0].value)
- .currency;
- const newDenominations = yield Promise.all(exchangeKeysJson.denoms.map(d => denominationRecordFromKeys(ws, baseUrl, d)));
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges, dbTypes.Stores.denominations], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.exchanges, baseUrl);
- if (!r) {
- console.warn(`exchange ${baseUrl} no longer present`);
- return;
- }
- if (r.details) ;
- r.details = {
- auditors: exchangeKeysJson.auditors,
- currency: currency,
- lastUpdateTime: lastUpdateTimestamp,
- masterPublicKey: exchangeKeysJson.master_public_key,
- protocolVersion: protocolVersion,
- };
- r.updateStatus = "fetch-wire" /* FetchWire */;
- r.lastError = undefined;
- yield tx.put(dbTypes.Stores.exchanges, r);
- for (const newDenom of newDenominations) {
- const oldDenom = yield tx.get(dbTypes.Stores.denominations, [
- baseUrl,
- newDenom.denomPub,
- ]);
- if (oldDenom) ;
- else {
- yield tx.put(dbTypes.Stores.denominations, newDenom);
- }
- }
- }));
- });
-}
-function updateExchangeFinalize(ws, exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
- const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!exchange) {
- return;
- }
- if (exchange.updateStatus != "finalize-update" /* FinalizeUpdate */) {
- return;
- }
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges, dbTypes.Stores.exchangeUpdatedEvents], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!r) {
- return;
- }
- if (r.updateStatus != "finalize-update" /* FinalizeUpdate */) {
- return;
- }
- r.updateStatus = "finished" /* Finished */;
- yield tx.put(dbTypes.Stores.exchanges, r);
- const updateEvent = {
- exchangeBaseUrl: exchange.baseUrl,
- timestamp: time.getTimestampNow(),
- };
- yield tx.put(dbTypes.Stores.exchangeUpdatedEvents, updateEvent);
- }));
- });
-}
-function updateExchangeWithTermsOfService(ws, exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
- const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!exchange) {
- return;
- }
- if (exchange.updateStatus != "fetch-terms" /* FetchTerms */) {
- return;
- }
- const reqUrl = new URL("terms", exchangeBaseUrl);
- reqUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
- const headers = {
- Accept: "text/plain",
- };
- const resp = yield ws.http.get(reqUrl.href, { headers });
- if (resp.status !== 200) {
- throw Error(`/terms response has unexpected status code (${resp.status})`);
- }
- const tosText = yield resp.text();
- const tosEtag = resp.headers.get("etag") || undefined;
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!r) {
- return;
- }
- if (r.updateStatus != "fetch-terms" /* FetchTerms */) {
- return;
- }
- r.termsOfServiceText = tosText;
- r.termsOfServiceLastEtag = tosEtag;
- r.updateStatus = "finalize-update" /* FinalizeUpdate */;
- yield tx.put(dbTypes.Stores.exchanges, r);
- }));
- });
-}
-function acceptExchangeTermsOfService(ws, exchangeBaseUrl, etag) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!r) {
- return;
- }
- r.termsOfServiceAcceptedEtag = etag;
- r.termsOfServiceAcceptedTimestamp = time.getTimestampNow();
- yield tx.put(dbTypes.Stores.exchanges, r);
- }));
- });
-}
-exports.acceptExchangeTermsOfService = acceptExchangeTermsOfService;
-/**
- * Fetch wire information for an exchange and store it in the database.
- *
- * @param exchangeBaseUrl Exchange base URL, assumed to be already normalized.
- */
-function updateExchangeWithWireInfo(ws, exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
- const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!exchange) {
- return;
- }
- if (exchange.updateStatus != "fetch-wire" /* FetchWire */) {
- return;
- }
- const details = exchange.details;
- if (!details) {
- throw Error("invalid exchange state");
- }
- const reqUrl = new URL("wire", exchangeBaseUrl);
- reqUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
- const resp = yield ws.http.get(reqUrl.href);
- if (resp.status !== 200) {
- throw Error(`/wire response has unexpected status code (${resp.status})`);
- }
- const wiJson = yield resp.json();
- if (!wiJson) {
- throw Error("/wire response malformed");
- }
- const wireInfo = talerTypes.codecForExchangeWireJson().decode(wiJson);
- for (const a of wireInfo.accounts) {
- console.log("validating exchange acct");
- const isValid = yield ws.cryptoApi.isValidWireAccount(a.payto_uri, a.master_sig, details.masterPublicKey);
- if (!isValid) {
- throw Error("exchange acct signature invalid");
- }
- }
- const feesForType = {};
- for (const wireMethod of Object.keys(wireInfo.fees)) {
- const feeList = [];
- for (const x of wireInfo.fees[wireMethod]) {
- const startStamp = x.start_date;
- const endStamp = x.end_date;
- const fee = {
- closingFee: Amounts.parseOrThrow(x.closing_fee),
- endStamp,
- sig: x.sig,
- startStamp,
- wireFee: Amounts.parseOrThrow(x.wire_fee),
- };
- const isValid = yield ws.cryptoApi.isValidWireFee(wireMethod, fee, details.masterPublicKey);
- if (!isValid) {
- throw Error("exchange wire fee signature invalid");
- }
- feeList.push(fee);
- }
- feesForType[wireMethod] = feeList;
- }
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!r) {
- return;
- }
- if (r.updateStatus != "fetch-wire" /* FetchWire */) {
- return;
- }
- r.wireInfo = {
- accounts: wireInfo.accounts,
- feesForType: feesForType,
- };
- r.updateStatus = "fetch-terms" /* FetchTerms */;
- r.lastError = undefined;
- yield tx.put(dbTypes.Stores.exchanges, r);
- }));
- });
-}
-function updateExchangeFromUrl(ws, baseUrl, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- const onOpErr = (e) => setExchangeError(ws, baseUrl, e);
- return yield errors.guardOperationException(() => updateExchangeFromUrlImpl(ws, baseUrl, forceNow), onOpErr);
- });
-}
-exports.updateExchangeFromUrl = updateExchangeFromUrl;
-/**
- * Update or add exchange DB entry by fetching the /keys and /wire information.
- * Optionally link the reserve entry to the new or existing
- * exchange entry in then DB.
- */
-function updateExchangeFromUrlImpl(ws, baseUrl, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- const now = time.getTimestampNow();
- baseUrl = helpers.canonicalizeBaseUrl(baseUrl);
- const r = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
- if (!r) {
- const newExchangeRecord = {
- builtIn: false,
- baseUrl: baseUrl,
- details: undefined,
- wireInfo: undefined,
- updateStatus: "fetch-keys" /* FetchKeys */,
- updateStarted: now,
- updateReason: "initial" /* Initial */,
- timestampAdded: time.getTimestampNow(),
- termsOfServiceAcceptedEtag: undefined,
- termsOfServiceAcceptedTimestamp: undefined,
- termsOfServiceLastEtag: undefined,
- termsOfServiceText: undefined,
- updateDiff: undefined,
- };
- yield ws.db.put(dbTypes.Stores.exchanges, newExchangeRecord);
- }
- else {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (t) => __awaiter(this, void 0, void 0, function* () {
- const rec = yield t.get(dbTypes.Stores.exchanges, baseUrl);
- if (!rec) {
- return;
- }
- if (rec.updateStatus != "fetch-keys" /* FetchKeys */ && !forceNow) {
- return;
- }
- if (rec.updateStatus != "fetch-keys" /* FetchKeys */ && forceNow) {
- rec.updateReason = "forced" /* Forced */;
- }
- rec.updateStarted = now;
- rec.updateStatus = "fetch-keys" /* FetchKeys */;
- rec.lastError = undefined;
- t.put(dbTypes.Stores.exchanges, rec);
- }));
- }
- yield updateExchangeWithKeys(ws, baseUrl);
- yield updateExchangeWithWireInfo(ws, baseUrl);
- yield updateExchangeWithTermsOfService(ws, baseUrl);
- yield updateExchangeFinalize(ws, baseUrl);
- const updatedExchange = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
- if (!updatedExchange) {
- // This should practically never happen
- throw Error("exchange not found");
- }
- return updatedExchange;
- });
-}
-/**
- * Check if and how an exchange is trusted and/or audited.
- */
-function getExchangeTrust(ws, exchangeInfo) {
- return __awaiter(this, void 0, void 0, function* () {
- let isTrusted = false;
- let isAudited = false;
- const exchangeDetails = exchangeInfo.details;
- if (!exchangeDetails) {
- throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
- }
- const currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, exchangeDetails.currency);
- if (currencyRecord) {
- for (const trustedExchange of currencyRecord.exchanges) {
- if (trustedExchange.exchangePub === exchangeDetails.masterPublicKey) {
- isTrusted = true;
- break;
- }
- }
- for (const trustedAuditor of currencyRecord.auditors) {
- for (const exchangeAuditor of exchangeDetails.auditors) {
- if (trustedAuditor.auditorPub === exchangeAuditor.auditor_pub) {
- isAudited = true;
- break;
- }
- }
- }
- }
- return { isTrusted, isAudited };
- });
-}
-exports.getExchangeTrust = getExchangeTrust;
-function getExchangePaytoUri(ws, exchangeBaseUrl, supportedTargetTypes) {
- return __awaiter(this, void 0, void 0, function* () {
- // We do the update here, since the exchange might not even exist
- // yet in our database.
- const exchangeRecord = yield updateExchangeFromUrl(ws, exchangeBaseUrl);
- if (!exchangeRecord) {
- throw Error(`Exchange '${exchangeBaseUrl}' not found.`);
- }
- const exchangeWireInfo = exchangeRecord.wireInfo;
- if (!exchangeWireInfo) {
- throw Error(`Exchange wire info for '${exchangeBaseUrl}' not found.`);
- }
- for (let account of exchangeWireInfo.accounts) {
- const res = payto.parsePaytoUri(account.payto_uri);
- if (!res) {
- continue;
- }
- if (supportedTargetTypes.includes(res.targetType)) {
- return account.payto_uri;
- }
- }
- throw Error("no matching exchange account found");
- });
-}
-exports.getExchangePaytoUri = getExchangePaytoUri;
-
-});
-
-unwrapExports(exchanges);
-var exchanges_1 = exchanges.acceptExchangeTermsOfService;
-var exchanges_2 = exchanges.updateExchangeFromUrl;
-var exchanges_3 = exchanges.getExchangeTrust;
-var exchanges_4 = exchanges.getExchangePaytoUri;
-
var libtoolVersion = createCommonjsModule(function (module, exports) {
/*
This file is part of TALER
@@ -3020,8 +2968,8 @@ function compare(me, other) {
if (!(meVer && otherVer)) {
return undefined;
}
- const compatible = (meVer.current - meVer.age <= otherVer.current &&
- meVer.current >= (otherVer.current - otherVer.age));
+ 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 };
}
@@ -3051,7 +2999,7 @@ function parseVersion(v) {
unwrapExports(libtoolVersion);
var libtoolVersion_1 = libtoolVersion.compare;
-var withdraw = createCommonjsModule(function (module, exports) {
+var assertUnreachable_1 = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
@@ -3067,514 +3015,16 @@ var withdraw = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-
-const Amounts = __importStar(amounts);
-
-
-
-
-
-const LibtoolVersion = __importStar(libtoolVersion);
-
-
-const logger = new logging.Logger("withdraw.ts");
-function isWithdrawableDenom(d) {
- const now = time.getTimestampNow();
- const started = time.timestampCmp(now, d.stampStart) >= 0;
- const lastPossibleWithdraw = time.timestampSubtractDuraction(d.stampExpireWithdraw, { d_ms: 50 * 1000 });
- const remaining = time.getDurationRemaining(lastPossibleWithdraw, now);
- const stillOkay = remaining.d_ms !== 0;
- return started && stillOkay;
-}
-/**
- * Get a list of denominations (with repetitions possible)
- * whose total value is as close as possible to the available
- * amount, but never larger.
- */
-function getWithdrawDenomList(amountAvailable, denoms) {
- let remaining = Amounts.copy(amountAvailable);
- const ds = [];
- denoms = denoms.filter(isWithdrawableDenom);
- denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value));
- // This is an arbitrary number of coins
- // we can withdraw in one go. It's not clear if this limit
- // is useful ...
- for (let i = 0; i < 1000; i++) {
- let found = false;
- for (const d of denoms) {
- const cost = Amounts.add(d.value, d.feeWithdraw).amount;
- if (Amounts.cmp(remaining, cost) < 0) {
- continue;
- }
- found = true;
- remaining = Amounts.sub(remaining, cost).amount;
- ds.push(d);
- break;
- }
- if (!found) {
- break;
- }
- }
- return ds;
-}
-exports.getWithdrawDenomList = getWithdrawDenomList;
-/**
- * Get information about a withdrawal from
- * a taler://withdraw URI by asking the bank.
- */
-function getBankWithdrawalInfo(ws, talerWithdrawUri) {
- return __awaiter(this, void 0, void 0, function* () {
- const uriResult = taleruri.parseWithdrawUri(talerWithdrawUri);
- if (!uriResult) {
- throw Error(`can't parse URL ${talerWithdrawUri}`);
- }
- const resp = yield ws.http.get(uriResult.statusUrl);
- if (resp.status !== 200) {
- throw Error(`unexpected status (${resp.status}) from bank for ${uriResult.statusUrl}`);
- }
- const respJson = yield resp.json();
- console.log("resp:", respJson);
- const status = talerTypes.codecForWithdrawOperationStatusResponse().decode(respJson);
- return {
- amount: Amounts.parseOrThrow(status.amount),
- confirmTransferUrl: status.confirm_transfer_url,
- extractedStatusUrl: uriResult.statusUrl,
- selectionDone: status.selection_done,
- senderWire: status.sender_wire,
- suggestedExchange: status.suggested_exchange,
- transferDone: status.transfer_done,
- wireTypes: status.wire_types,
- };
- });
-}
-exports.getBankWithdrawalInfo = getBankWithdrawalInfo;
-function getPossibleDenoms(ws, exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
- return yield ws.db
- .iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, exchangeBaseUrl)
- .filter(d => {
- return (d.status === dbTypes.DenominationStatus.Unverified ||
- d.status === dbTypes.DenominationStatus.VerifiedGood);
- });
- });
-}
-/**
- * Given a planchet, withdraw a coin from the exchange.
- */
-function processPlanchet(ws, withdrawalSessionId, coinIdx) {
- return __awaiter(this, void 0, void 0, function* () {
- const withdrawalSession = yield ws.db.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!withdrawalSession) {
- return;
- }
- if (withdrawalSession.withdrawn[coinIdx]) {
- return;
- }
- if (withdrawalSession.source.type === "reserve") ;
- const planchet = withdrawalSession.planchets[coinIdx];
- if (!planchet) {
- console.log("processPlanchet: planchet not found");
- return;
- }
- const exchange = yield ws.db.get(dbTypes.Stores.exchanges, withdrawalSession.exchangeBaseUrl);
- if (!exchange) {
- console.error("db inconsistent: exchange for planchet not found");
- return;
- }
- const denom = yield ws.db.get(dbTypes.Stores.denominations, [
- withdrawalSession.exchangeBaseUrl,
- planchet.denomPub,
- ]);
- if (!denom) {
- console.error("db inconsistent: denom for planchet not found");
- return;
- }
- const wd = {};
- wd.denom_pub_hash = planchet.denomPubHash;
- wd.reserve_pub = planchet.reservePub;
- wd.reserve_sig = planchet.withdrawSig;
- wd.coin_ev = planchet.coinEv;
- const reqUrl = new URL("reserve/withdraw", exchange.baseUrl).href;
- const resp = yield ws.http.postJson(reqUrl, wd);
- if (resp.status !== 200) {
- throw Error(`unexpected status ${resp.status} for withdraw`);
- }
- const r = yield resp.json();
- const denomSig = yield ws.cryptoApi.rsaUnblind(r.ev_sig, planchet.blindingKey, planchet.denomPub);
- const isValid = yield ws.cryptoApi.rsaVerify(planchet.coinPub, denomSig, planchet.denomPub);
- if (!isValid) {
- throw Error("invalid RSA signature by the exchange");
- }
- const coin = {
- blindingKey: planchet.blindingKey,
- coinPriv: planchet.coinPriv,
- coinPub: planchet.coinPub,
- currentAmount: planchet.coinValue,
- denomPub: planchet.denomPub,
- denomPubHash: planchet.denomPubHash,
- denomSig,
- exchangeBaseUrl: withdrawalSession.exchangeBaseUrl,
- reservePub: planchet.reservePub,
- status: dbTypes.CoinStatus.Fresh,
- coinIndex: coinIdx,
- withdrawSessionId: withdrawalSessionId,
- };
- let withdrawSessionFinished = false;
- let reserveDepleted = false;
- const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.withdrawalSession, dbTypes.Stores.reserves], (tx) => __awaiter(this, void 0, void 0, function* () {
- const ws = yield tx.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!ws) {
- return false;
- }
- if (ws.withdrawn[coinIdx]) {
- // Already withdrawn
- return false;
- }
- ws.withdrawn[coinIdx] = true;
- delete ws.lastErrorPerCoin[coinIdx];
- let numDone = 0;
- for (let i = 0; i < ws.withdrawn.length; i++) {
- if (ws.withdrawn[i]) {
- numDone++;
- }
- }
- if (numDone === ws.denoms.length) {
- ws.timestampFinish = time.getTimestampNow();
- ws.lastError = undefined;
- ws.retryInfo = dbTypes.initRetryInfo(false);
- withdrawSessionFinished = true;
- }
- yield tx.put(dbTypes.Stores.withdrawalSession, ws);
- if (!planchet.isFromTip) {
- const r = yield tx.get(dbTypes.Stores.reserves, planchet.reservePub);
- if (r) {
- r.amountWithdrawCompleted = Amounts.add(r.amountWithdrawCompleted, Amounts.add(denom.value, denom.feeWithdraw).amount).amount;
- if (Amounts.cmp(r.amountWithdrawCompleted, r.amountWithdrawAllocated) ==
- 0) {
- reserveDepleted = true;
- }
- yield tx.put(dbTypes.Stores.reserves, r);
- }
- }
- yield tx.add(dbTypes.Stores.coins, coin);
- return true;
- }));
- if (success) {
- ws.notify({
- type: "coin-withdrawn" /* CoinWithdrawn */,
- });
- }
- if (withdrawSessionFinished) {
- ws.notify({
- type: "withdraw-session-finished" /* WithdrawSessionFinished */,
- withdrawSessionId: withdrawalSessionId,
- });
- }
- if (reserveDepleted && withdrawalSession.source.type === "reserve") {
- ws.notify({
- type: "reserve-depleted" /* ReserveDepleted */,
- reservePub: withdrawalSession.source.reservePub,
- });
- }
- });
-}
-/**
- * Get a list of denominations to withdraw from the given exchange for the
- * given amount, making sure that all denominations' signatures are verified.
- *
- * Writes to the DB in order to record the result from verifying
- * denominations.
- */
-function getVerifiedWithdrawDenomList(ws, exchangeBaseUrl, amount) {
- return __awaiter(this, void 0, void 0, function* () {
- const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
- if (!exchange) {
- console.log("exchange not found");
- throw Error(`exchange ${exchangeBaseUrl} not found`);
- }
- const exchangeDetails = exchange.details;
- if (!exchangeDetails) {
- console.log("exchange details not available");
- throw Error(`exchange ${exchangeBaseUrl} details not available`);
- }
- console.log("getting possible denoms");
- const possibleDenoms = yield getPossibleDenoms(ws, exchange.baseUrl);
- console.log("got possible denoms");
- let allValid = false;
- let selectedDenoms;
- do {
- allValid = true;
- selectedDenoms = getWithdrawDenomList(amount, possibleDenoms);
- console.log("got withdraw denom list");
- for (const denom of selectedDenoms || []) {
- if (denom.status === dbTypes.DenominationStatus.Unverified) {
- console.log("checking validity", denom, exchangeDetails.masterPublicKey);
- const valid = yield ws.cryptoApi.isValidDenom(denom, exchangeDetails.masterPublicKey);
- console.log("done checking validity");
- if (!valid) {
- denom.status = dbTypes.DenominationStatus.VerifiedBad;
- allValid = false;
- }
- else {
- denom.status = dbTypes.DenominationStatus.VerifiedGood;
- }
- yield ws.db.put(dbTypes.Stores.denominations, denom);
- }
- }
- } while (selectedDenoms.length > 0 && !allValid);
- console.log("returning denoms");
- return selectedDenoms;
- });
-}
-exports.getVerifiedWithdrawDenomList = getVerifiedWithdrawDenomList;
-function makePlanchet(ws, withdrawalSessionId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
- const withdrawalSession = yield ws.db.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!withdrawalSession) {
- return;
- }
- const src = withdrawalSession.source;
- if (src.type !== "reserve") {
- throw Error("invalid state");
- }
- const reserve = yield ws.db.get(dbTypes.Stores.reserves, src.reservePub);
- if (!reserve) {
- return;
- }
- const denom = yield ws.db.get(dbTypes.Stores.denominations, [
- withdrawalSession.exchangeBaseUrl,
- withdrawalSession.denoms[coinIndex],
- ]);
- if (!denom) {
- return;
- }
- const r = yield ws.cryptoApi.createPlanchet({
- denomPub: denom.denomPub,
- feeWithdraw: denom.feeWithdraw,
- reservePriv: reserve.reservePriv,
- reservePub: reserve.reservePub,
- value: denom.value,
- });
- const newPlanchet = {
- blindingKey: r.blindingKey,
- coinEv: r.coinEv,
- coinPriv: r.coinPriv,
- coinPub: r.coinPub,
- coinValue: r.coinValue,
- denomPub: r.denomPub,
- denomPubHash: r.denomPubHash,
- isFromTip: false,
- reservePub: r.reservePub,
- withdrawSig: r.withdrawSig,
- };
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.withdrawalSession], (tx) => __awaiter(this, void 0, void 0, function* () {
- const myWs = yield tx.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!myWs) {
- return;
- }
- if (myWs.planchets[coinIndex]) {
- return;
- }
- myWs.planchets[coinIndex] = newPlanchet;
- yield tx.put(dbTypes.Stores.withdrawalSession, myWs);
- }));
- });
-}
-function processWithdrawCoin(ws, withdrawalSessionId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
- logger.trace("starting withdraw for coin", coinIndex);
- const withdrawalSession = yield ws.db.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!withdrawalSession) {
- console.log("ws doesn't exist");
- return;
- }
- const coin = yield ws.db.getIndexed(dbTypes.Stores.coins.byWithdrawalWithIdx, [
- withdrawalSessionId,
- coinIndex,
- ]);
- if (coin) {
- console.log("coin already exists");
- return;
- }
- if (!withdrawalSession.planchets[coinIndex]) {
- const key = `${withdrawalSessionId}-${coinIndex}`;
- yield ws.memoMakePlanchet.memo(key, () => __awaiter(this, void 0, void 0, function* () {
- logger.trace("creating planchet for coin", coinIndex);
- return makePlanchet(ws, withdrawalSessionId, coinIndex);
- }));
- }
- yield processPlanchet(ws, withdrawalSessionId, coinIndex);
- });
-}
-function incrementWithdrawalRetry(ws, withdrawalSessionId, err) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.withdrawalSession], (tx) => __awaiter(this, void 0, void 0, function* () {
- const wsr = yield tx.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!wsr) {
- return;
- }
- if (!wsr.retryInfo) {
- return;
- }
- wsr.retryInfo.retryCounter++;
- dbTypes.updateRetryInfoTimeout(wsr.retryInfo);
- wsr.lastError = err;
- yield tx.put(dbTypes.Stores.withdrawalSession, wsr);
- }));
- ws.notify({ type: "withdraw-error" /* WithdrawOperationError */ });
- });
-}
-function processWithdrawSession(ws, withdrawalSessionId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- const onOpErr = (e) => incrementWithdrawalRetry(ws, withdrawalSessionId, e);
- yield errors.guardOperationException(() => processWithdrawSessionImpl(ws, withdrawalSessionId, forceNow), onOpErr);
- });
-}
-exports.processWithdrawSession = processWithdrawSession;
-function resetWithdrawSessionRetry(ws, withdrawalSessionId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.withdrawalSession, withdrawalSessionId, x => {
- if (x.retryInfo.active) {
- x.retryInfo = dbTypes.initRetryInfo();
- }
- return x;
- });
- });
-}
-function processWithdrawSessionImpl(ws, withdrawalSessionId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
- logger.trace("processing withdraw session", withdrawalSessionId);
- if (forceNow) {
- yield resetWithdrawSessionRetry(ws, withdrawalSessionId);
- }
- const withdrawalSession = yield ws.db.get(dbTypes.Stores.withdrawalSession, withdrawalSessionId);
- if (!withdrawalSession) {
- logger.trace("withdraw session doesn't exist");
- return;
- }
- const ps = withdrawalSession.denoms.map((d, i) => processWithdrawCoin(ws, withdrawalSessionId, i));
- yield Promise.all(ps);
- return;
- });
-}
-function getExchangeWithdrawalInfo(ws, baseUrl, amount) {
- return __awaiter(this, void 0, void 0, function* () {
- const exchangeInfo = yield exchanges.updateExchangeFromUrl(ws, baseUrl);
- const exchangeDetails = exchangeInfo.details;
- if (!exchangeDetails) {
- throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
- }
- const exchangeWireInfo = exchangeInfo.wireInfo;
- if (!exchangeWireInfo) {
- throw Error(`exchange ${exchangeInfo.baseUrl} wire details not available`);
- }
- const selectedDenoms = yield getVerifiedWithdrawDenomList(ws, baseUrl, amount);
- let acc = Amounts.getZero(amount.currency);
- for (const d of selectedDenoms) {
- acc = Amounts.add(acc, d.feeWithdraw).amount;
- }
- const actualCoinCost = selectedDenoms
- .map((d) => Amounts.add(d.value, d.feeWithdraw).amount)
- .reduce((a, b) => Amounts.add(a, b).amount);
- const exchangeWireAccounts = [];
- for (let account of exchangeWireInfo.accounts) {
- exchangeWireAccounts.push(account.payto_uri);
- }
- const { isTrusted, isAudited } = yield exchanges.getExchangeTrust(ws, exchangeInfo);
- let earliestDepositExpiration = selectedDenoms[0].stampExpireDeposit;
- for (let i = 1; i < selectedDenoms.length; i++) {
- const expireDeposit = selectedDenoms[i].stampExpireDeposit;
- if (expireDeposit.t_ms < earliestDepositExpiration.t_ms) {
- earliestDepositExpiration = expireDeposit;
- }
- }
- const possibleDenoms = yield ws.db
- .iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, baseUrl)
- .filter(d => d.isOffered);
- const trustedAuditorPubs = [];
- const currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, amount.currency);
- if (currencyRecord) {
- trustedAuditorPubs.push(...currencyRecord.auditors.map(a => a.auditorPub));
- }
- let versionMatch;
- if (exchangeDetails.protocolVersion) {
- versionMatch = LibtoolVersion.compare(versions.WALLET_EXCHANGE_PROTOCOL_VERSION, exchangeDetails.protocolVersion);
- if (versionMatch &&
- !versionMatch.compatible &&
- versionMatch.currentCmp === -1) {
- console.warn(`wallet's support for exchange protocol version ${versions.WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
- `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`);
- }
- }
- let tosAccepted = false;
- if (exchangeInfo.termsOfServiceAcceptedTimestamp) {
- if (exchangeInfo.termsOfServiceAcceptedEtag ==
- exchangeInfo.termsOfServiceLastEtag) {
- tosAccepted = true;
- }
- }
- const ret = {
- earliestDepositExpiration,
- exchangeInfo,
- exchangeWireAccounts,
- exchangeVersion: exchangeDetails.protocolVersion || "unknown",
- isAudited,
- isTrusted,
- numOfferedDenoms: possibleDenoms.length,
- overhead: Amounts.sub(amount, actualCoinCost).amount,
- selectedDenoms,
- trustedAuditorPubs,
- versionMatch,
- walletVersion: versions.WALLET_EXCHANGE_PROTOCOL_VERSION,
- wireFees: exchangeWireInfo,
- withdrawFee: acc,
- termsOfServiceAccepted: tosAccepted,
- };
- return ret;
- });
-}
-exports.getExchangeWithdrawalInfo = getExchangeWithdrawalInfo;
-function getWithdrawDetailsForUri(ws, talerWithdrawUri, maybeSelectedExchange) {
- return __awaiter(this, void 0, void 0, function* () {
- const info = yield getBankWithdrawalInfo(ws, talerWithdrawUri);
- let rci = undefined;
- if (maybeSelectedExchange) {
- rci = yield getExchangeWithdrawalInfo(ws, maybeSelectedExchange, info.amount);
- }
- return {
- bankWithdrawDetails: info,
- exchangeWithdrawDetails: rci,
- };
- });
+function assertUnreachable(x) {
+ throw new Error("Didn't expect to get here");
}
-exports.getWithdrawDetailsForUri = getWithdrawDetailsForUri;
+exports.assertUnreachable = assertUnreachable;
});
-unwrapExports(withdraw);
-var withdraw_1 = withdraw.getWithdrawDenomList;
-var withdraw_2 = withdraw.getBankWithdrawalInfo;
-var withdraw_3 = withdraw.getVerifiedWithdrawDenomList;
-var withdraw_4 = withdraw.processWithdrawSession;
-var withdraw_5 = withdraw.getExchangeWithdrawalInfo;
-var withdraw_6 = withdraw.getWithdrawDetailsForUri;
+unwrapExports(assertUnreachable_1);
+var assertUnreachable_2 = assertUnreachable_1.assertUnreachable;
var naclFast = createCommonjsModule(function (module, exports) {
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
@@ -3595,7 +3045,6 @@ const gf = function (init = []) {
let randombytes = function (x, n) {
throw new Error("no PRNG");
};
-const _0 = new Uint8Array(16);
const _9 = new Uint8Array(32);
_9[0] = 9;
// prettier-ignore
@@ -3703,801 +3152,21 @@ function ts64(x, i, h, l) {
x[i + 7] = l & 0xff;
}
function vn(x, xi, y, yi, n) {
- var i, d = 0;
+ 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);
}
-// prettier-ignore
-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;
-}
-function crypto_core_salsa20(out, inp, k, c) {
- core_salsa20(out, inp, k, c);
-}
-function crypto_core_hsalsa20(out, inp, k, c) {
- core_hsalsa20(out, inp, k, c);
-}
-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) {
- crypto_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) {
- crypto_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) {
- crypto_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) {
- crypto_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);
- crypto_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);
- crypto_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) {
- var i, 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) {
- var i;
+ let i;
for (i = 0; i < 16; i++)
r[i] = a[i] | 0;
}
function car25519(o) {
- var i, v, c = 1;
+ let i, v, c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
@@ -4506,16 +3175,17 @@ function car25519(o) {
o[0] += c - 1 + 37 * (c - 1);
}
function sel25519(p, q, b) {
- var t, c = ~(b - 1);
- for (var i = 0; i < 16; i++) {
+ 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) {
- var i, j, b;
- var m = gf(), t = gf();
+ let i, j, b;
+ const m = gf(), t = gf();
for (i = 0; i < 16; i++)
t[i] = n[i];
car25519(t);
@@ -4538,32 +3208,33 @@ function pack25519(o, n) {
}
}
function neq25519(a, b) {
- var c = new Uint8Array(32), d = new Uint8Array(32);
+ 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) {
- var d = new Uint8Array(32);
+ const d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
}
function unpack25519(o, n) {
- var i;
+ 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 (var i = 0; i < 16; i++)
+ for (let i = 0; i < 16; i++)
o[i] = a[i] + b[i];
}
function Z(o, a, b) {
- for (var i = 0; i < 16; i++)
+ for (let i = 0; i < 16; i++)
o[i] = a[i] - b[i];
}
function M(o, a, b) {
- var 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, 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];
+ 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;
@@ -4975,8 +3646,8 @@ function S(o, a) {
M(o, a, a);
}
function inv25519(o, i) {
- var c = gf();
- var a;
+ const c = gf();
+ let a;
for (a = 0; a < 16; a++)
c[a] = i[a];
for (a = 253; a >= 0; a--) {
@@ -4988,8 +3659,8 @@ function inv25519(o, i) {
o[a] = c[a];
}
function pow2523(o, i) {
- var c = gf();
- var a;
+ const c = gf();
+ let a;
for (a = 0; a < 16; a++)
c[a] = i[a];
for (a = 250; a >= 0; a--) {
@@ -5001,9 +3672,11 @@ function pow2523(o, i) {
o[a] = c[a];
}
function crypto_scalarmult(q, n, p) {
- var z = new Uint8Array(32);
- var x = new Float64Array(80), r, i;
- var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf();
+ 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;
@@ -5045,8 +3718,8 @@ function crypto_scalarmult(q, n, p) {
x[i + 48] = b[i];
x[i + 64] = d[i];
}
- var x32 = x.subarray(32);
- var x16 = x.subarray(16);
+ const x32 = x.subarray(32);
+ const x16 = x.subarray(16);
inv25519(x32, x32);
M(x16, x16, x32);
pack25519(q, x16);
@@ -5055,17 +3728,8 @@ function crypto_scalarmult(q, n, p) {
function crypto_scalarmult_base(q, n) {
return crypto_scalarmult(q, n, _9);
}
-function crypto_box_keypair(y, x) {
- randombytes(x, 32);
- return crypto_scalarmult_base(y, x);
-}
-function crypto_box_beforenm(k, y, x) {
- var s = new Uint8Array(32);
- crypto_scalarmult(s, x, y);
- return crypto_core_hsalsa20(k, _0, s, sigma);
-}
// prettier-ignore
-var K = [
+const K = [
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
@@ -5108,9 +3772,10 @@ var K = [
0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
];
function crypto_hashblocks_hl(hh, hl, m, n) {
- var wh = new Int32Array(16), wl = new Int32Array(16), 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;
- var 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];
- var pos = 0;
+ 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;
@@ -5445,7 +4110,7 @@ function crypto_hash(out, m, n) {
const hh = new Int32Array(8);
const hl = new Int32Array(8);
const x = new Uint8Array(256);
- let b = n;
+ const b = n;
hh[0] = 0x6a09e667;
hh[1] = 0xbb67ae85;
hh[2] = 0x3c6ef372;
@@ -5507,7 +4172,7 @@ class HashState {
let i = 0;
while (i < data.length) {
const r = 128 - this.p;
- if (r > (data.length - i)) {
+ if (r > data.length - i) {
for (let j = 0; i + j < data.length; j++) {
this.next[this.p + j] = data[i + j];
}
@@ -5529,7 +4194,7 @@ class HashState {
const out = new Uint8Array(64);
let n = this.p;
const x = new Uint8Array(256);
- let b = this.total;
+ const b = this.total;
for (let i = 0; i < n; i++)
x[i] = this.next[i];
x[n] = 128;
@@ -5544,7 +4209,7 @@ class HashState {
}
exports.HashState = HashState;
function add(p, q) {
- var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf();
+ 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);
@@ -5565,13 +4230,13 @@ function add(p, q) {
M(p[3], e, h);
}
function cswap(p, q, b) {
- var i;
+ let i;
for (i = 0; i < 4; i++) {
sel25519(p[i], q[i], b);
}
}
function pack(r, p) {
- var tx = gf(), ty = gf(), zi = gf();
+ const tx = gf(), ty = gf(), zi = gf();
inv25519(zi, p[2]);
M(tx, p[0], zi);
M(ty, p[1], zi);
@@ -5579,7 +4244,7 @@ function pack(r, p) {
r[31] ^= par25519(tx) << 7;
}
function scalarmult(p, q, s) {
- var b, i;
+ let b, i;
set25519(p[0], gf0);
set25519(p[1], gf1);
set25519(p[2], gf1);
@@ -5615,7 +4280,7 @@ function crypto_sign_keypair(pk, sk, seeded) {
sk[i + 32] = pk[i];
return 0;
}
-var L = new Float64Array([
+const L = new Float64Array([
0xed,
0xd3,
0xf5,
@@ -5650,7 +4315,7 @@ var L = new Float64Array([
0x10,
]);
function modL(r, x) {
- var carry, i, j, k;
+ let carry, i, j, k;
for (i = 63; i >= 32; --i) {
carry = 0;
for (j = i - 32, k = i - 12; j < k; ++j) {
@@ -5684,14 +4349,15 @@ function reduce(r) {
}
// Note: difference from C - smlen returned, not passed as argument.
function crypto_sign(sm, m, n, sk) {
- var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
- var i, j, x = new Float64Array(64);
- var p = [gf(), gf(), gf(), gf()];
+ 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;
- var smlen = n + 64;
+ const smlen = n + 64;
for (i = 0; i < n; i++)
sm[64 + i] = m[i];
for (i = 0; i < 32; i++)
@@ -5754,9 +4420,9 @@ function unpackneg(r, p) {
return 0;
}
function crypto_sign_open(m, sm, n, pk) {
- var i, mlen;
- var t = new Uint8Array(32), h = new Uint8Array(64);
- var p = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()];
+ 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;
@@ -5783,71 +4449,31 @@ function crypto_sign_open(m, sm, n, pk) {
mlen = n;
return mlen;
}
-var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, crypto_secretbox_BOXZEROBYTES = 16, crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_box_PUBLICKEYBYTES = 32, crypto_box_SECRETKEYBYTES = 32, crypto_box_BEFORENMBYTES = 32, crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64;
+const crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, 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 checkBoxLengths(pk, sk) {
- if (pk.length !== crypto_box_PUBLICKEYBYTES)
- throw new Error("bad public key size");
- if (sk.length !== crypto_box_SECRETKEYBYTES)
- throw new Error("bad secret key size");
-}
function checkArrayTypes(...args) {
- for (var i = 0; i < args.length; i++) {
+ for (let i = 0; i < args.length; i++) {
if (!(args[i] instanceof Uint8Array))
throw new TypeError("unexpected type, use Uint8Array");
}
}
function cleanup(arr) {
- for (var i = 0; i < arr.length; i++)
+ for (let i = 0; i < arr.length; i++)
arr[i] = 0;
}
function randomBytes(n) {
- var b = new Uint8Array(n);
+ const b = new Uint8Array(n);
randombytes(b, n);
return b;
}
exports.randomBytes = randomBytes;
-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);
-}
-exports.secretbox = secretbox;
-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 null;
- if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0)
- return null;
- return m.subarray(crypto_secretbox_ZEROBYTES);
-}
-exports.secretbox_open = secretbox_open;
-exports.secretbox_keyLength = crypto_secretbox_KEYBYTES;
-exports.secretbox_nonceLength = crypto_secretbox_NONCEBYTES;
-exports.secretbox_overheadLength = crypto_secretbox_BOXZEROBYTES;
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");
- var q = new Uint8Array(crypto_scalarmult_BYTES);
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
crypto_scalarmult(q, n, p);
return q;
}
@@ -5856,59 +4482,18 @@ function scalarMult_base(n) {
checkArrayTypes(n);
if (n.length !== crypto_scalarmult_SCALARBYTES)
throw new Error("bad n size");
- var q = new Uint8Array(crypto_scalarmult_BYTES);
+ const q = new Uint8Array(crypto_scalarmult_BYTES);
crypto_scalarmult_base(q, n);
return q;
}
exports.scalarMult_base = scalarMult_base;
exports.scalarMult_scalarLength = crypto_scalarmult_SCALARBYTES;
exports.scalarMult_groupElementLength = crypto_scalarmult_BYTES;
-function box(msg, nonce, publicKey, secretKey) {
- var k = box_before(publicKey, secretKey);
- return secretbox(msg, nonce, k);
-}
-exports.box = box;
-function box_before(publicKey, secretKey) {
- checkArrayTypes(publicKey, secretKey);
- checkBoxLengths(publicKey, secretKey);
- var k = new Uint8Array(crypto_box_BEFORENMBYTES);
- crypto_box_beforenm(k, publicKey, secretKey);
- return k;
-}
-exports.box_before = box_before;
-exports.box_after = secretbox;
-function box_open(msg, nonce, publicKey, secretKey) {
- var k = box_before(publicKey, secretKey);
- return secretbox_open(msg, nonce, k);
-}
-exports.box_open = box_open;
-exports.box_open_after = secretbox_open;
-function box_keyPair() {
- var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
- var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
- crypto_box_keypair(pk, sk);
- return { publicKey: pk, secretKey: sk };
-}
-exports.box_keyPair = box_keyPair;
-function box_keyPair_fromSecretKey(secretKey) {
- checkArrayTypes(secretKey);
- if (secretKey.length !== crypto_box_SECRETKEYBYTES)
- throw new Error("bad secret key size");
- var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
- crypto_scalarmult_base(pk, secretKey);
- return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
-}
-exports.box_keyPair_fromSecretKey = box_keyPair_fromSecretKey;
-exports.box_publicKeyLength = crypto_box_PUBLICKEYBYTES;
-exports.box_secretKeyLength = crypto_box_SECRETKEYBYTES;
-exports.box_sharedKeyLength = crypto_box_BEFORENMBYTES;
-exports.box_nonceLength = crypto_box_NONCEBYTES;
-exports.box_overheadLength = exports.secretbox_overheadLength;
function sign(msg, secretKey) {
checkArrayTypes(msg, secretKey);
if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
throw new Error("bad secret key size");
- var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
+ const signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
crypto_sign(signedMsg, msg, msg.length, secretKey);
return signedMsg;
}
@@ -5917,20 +4502,20 @@ function sign_open(signedMsg, publicKey) {
checkArrayTypes(signedMsg, publicKey);
if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
throw new Error("bad public key size");
- var tmp = new Uint8Array(signedMsg.length);
- var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
+ const tmp = new Uint8Array(signedMsg.length);
+ const mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
if (mlen < 0)
return null;
- var m = new Uint8Array(mlen);
- for (var i = 0; i < m.length; i++)
+ const m = new Uint8Array(mlen);
+ for (let i = 0; i < m.length; i++)
m[i] = tmp[i];
return m;
}
exports.sign_open = sign_open;
function sign_detached(msg, secretKey) {
- var signedMsg = sign(msg, secretKey);
- var sig = new Uint8Array(crypto_sign_BYTES);
- for (var i = 0; i < sig.length; i++)
+ 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;
}
@@ -5941,9 +4526,9 @@ function sign_detached_verify(msg, sig, publicKey) {
throw new Error("bad signature size");
if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
throw new Error("bad public key size");
- var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
- var m = new Uint8Array(crypto_sign_BYTES + msg.length);
- var i;
+ 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++)
@@ -5952,8 +4537,8 @@ function sign_detached_verify(msg, sig, publicKey) {
}
exports.sign_detached_verify = sign_detached_verify;
function sign_keyPair() {
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
- var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
+ const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ const sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
crypto_sign_keypair(pk, sk, false);
return { publicKey: pk, secretKey: sk };
}
@@ -5979,8 +4564,8 @@ function sign_keyPair_fromSecretKey(secretKey) {
checkArrayTypes(secretKey);
if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
throw new Error("bad secret key size");
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
- for (var i = 0; i < pk.length; i++)
+ const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
+ for (let i = 0; i < pk.length; i++)
pk[i] = secretKey[32 + i];
return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
}
@@ -5989,9 +4574,9 @@ function sign_keyPair_fromSeed(seed) {
checkArrayTypes(seed);
if (seed.length !== crypto_sign_SEEDBYTES)
throw new Error("bad seed size");
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
- var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
- for (var i = 0; i < 32; i++)
+ 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 };
@@ -6003,7 +4588,7 @@ exports.sign_seedLength = crypto_sign_SEEDBYTES;
exports.sign_signatureLength = crypto_sign_BYTES;
function hash(msg) {
checkArrayTypes(msg);
- var h = new Uint8Array(crypto_hash_BYTES);
+ const h = new Uint8Array(crypto_hash_BYTES);
crypto_hash(h, msg, msg.length);
return h;
}
@@ -6044,14 +4629,15 @@ exports.sign_ed25519_pk_to_curve25519 = sign_ed25519_pk_to_curve25519;
(function () {
// Initialize PRNG if environment provides CSPRNG.
// If not, methods calling randombytes will throw.
- const crypto$1 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
- if (crypto$1 && crypto$1.getRandomValues) {
+ const cr = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
+ if (cr && cr.getRandomValues) {
// Browsers.
- var QUOTA = 65536;
+ const QUOTA = 65536;
setPRNG(function (x, n) {
- var i, v = new Uint8Array(n);
+ let i;
+ const v = new Uint8Array(n);
for (i = 0; i < n; i += QUOTA) {
- crypto$1.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
+ cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
}
for (i = 0; i < n; i++)
x[i] = v[i];
@@ -6060,11 +4646,12 @@ exports.sign_ed25519_pk_to_curve25519 = sign_ed25519_pk_to_curve25519;
}
else if (typeof require !== "undefined") {
// Node.js.
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
const cr = crypto;
if (cr && cr.randomBytes) {
setPRNG(function (x, n) {
- var i, v = cr.randomBytes(n);
- for (i = 0; i < n; i++)
+ const v = cr.randomBytes(n);
+ for (let i = 0; i < n; i++)
x[i] = v[i];
cleanup(v);
});
@@ -6077,1491 +4664,1474 @@ exports.sign_ed25519_pk_to_curve25519 = sign_ed25519_pk_to_curve25519;
unwrapExports(naclFast);
var naclFast_1 = naclFast.HashState;
var naclFast_2 = naclFast.randomBytes;
-var naclFast_3 = naclFast.secretbox;
-var naclFast_4 = naclFast.secretbox_open;
-var naclFast_5 = naclFast.secretbox_keyLength;
-var naclFast_6 = naclFast.secretbox_nonceLength;
-var naclFast_7 = naclFast.secretbox_overheadLength;
-var naclFast_8 = naclFast.scalarMult;
-var naclFast_9 = naclFast.scalarMult_base;
-var naclFast_10 = naclFast.scalarMult_scalarLength;
-var naclFast_11 = naclFast.scalarMult_groupElementLength;
-var naclFast_12 = naclFast.box;
-var naclFast_13 = naclFast.box_before;
-var naclFast_14 = naclFast.box_after;
-var naclFast_15 = naclFast.box_open;
-var naclFast_16 = naclFast.box_open_after;
-var naclFast_17 = naclFast.box_keyPair;
-var naclFast_18 = naclFast.box_keyPair_fromSecretKey;
-var naclFast_19 = naclFast.box_publicKeyLength;
-var naclFast_20 = naclFast.box_secretKeyLength;
-var naclFast_21 = naclFast.box_sharedKeyLength;
-var naclFast_22 = naclFast.box_nonceLength;
-var naclFast_23 = naclFast.box_overheadLength;
-var naclFast_24 = naclFast.sign;
-var naclFast_25 = naclFast.sign_open;
-var naclFast_26 = naclFast.sign_detached;
-var naclFast_27 = naclFast.sign_detached_verify;
-var naclFast_28 = naclFast.sign_keyPair;
-var naclFast_29 = naclFast.x25519_edwards_keyPair_fromSecretKey;
-var naclFast_30 = naclFast.sign_keyPair_fromSecretKey;
-var naclFast_31 = naclFast.sign_keyPair_fromSeed;
-var naclFast_32 = naclFast.sign_publicKeyLength;
-var naclFast_33 = naclFast.sign_secretKeyLength;
-var naclFast_34 = naclFast.sign_seedLength;
-var naclFast_35 = naclFast.sign_signatureLength;
-var naclFast_36 = naclFast.hash;
-var naclFast_37 = naclFast.hash_hashLength;
-var naclFast_38 = naclFast.verify;
-var naclFast_39 = naclFast.setPRNG;
-var naclFast_40 = naclFast.sign_ed25519_pk_to_curve25519;
+var naclFast_3 = naclFast.scalarMult;
+var naclFast_4 = naclFast.scalarMult_base;
+var naclFast_5 = naclFast.scalarMult_scalarLength;
+var naclFast_6 = naclFast.scalarMult_groupElementLength;
+var naclFast_7 = naclFast.sign;
+var naclFast_8 = naclFast.sign_open;
+var naclFast_9 = naclFast.sign_detached;
+var naclFast_10 = naclFast.sign_detached_verify;
+var naclFast_11 = naclFast.sign_keyPair;
+var naclFast_12 = naclFast.x25519_edwards_keyPair_fromSecretKey;
+var naclFast_13 = naclFast.sign_keyPair_fromSecretKey;
+var naclFast_14 = naclFast.sign_keyPair_fromSeed;
+var naclFast_15 = naclFast.sign_publicKeyLength;
+var naclFast_16 = naclFast.sign_secretKeyLength;
+var naclFast_17 = naclFast.sign_seedLength;
+var naclFast_18 = naclFast.sign_signatureLength;
+var naclFast_19 = naclFast.hash;
+var naclFast_20 = naclFast.hash_hashLength;
+var naclFast_21 = naclFast.verify;
+var naclFast_22 = naclFast.setPRNG;
+var naclFast_23 = naclFast.sign_ed25519_pk_to_curve25519;
var BigInteger = createCommonjsModule(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] : BASE;
- var digit = truncate(usedRNG() * top);
- result.push(digit);
- if (digit < top) 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;
-}
+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] : BASE;
+ var digit = truncate(usedRNG() * top);
+ result.push(digit);
+ if (digit < top) 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;
+}
});
var sha256_1 = createCommonjsModule(function (module, exports) {
@@ -7855,10 +6425,7 @@ class HMAC {
this.digestLength = this.inner.digestLength;
const pad = new Uint8Array(this.blockSize);
if (key.length > this.blockSize) {
- new HashSha256()
- .update(key)
- .finish(pad)
- .clean();
+ new HashSha256().update(key).finish(pad).clean();
}
else {
for (let i = 0; i < key.length; i++) {
@@ -7966,9 +6533,10 @@ var kdf_1 = createCommonjsModule(function (module, exports) {
*/
Object.defineProperty(exports, "__esModule", { value: true });
+const nacl = tslib_1.__importStar(naclFast);
function sha512(data) {
- return naclFast.hash(data);
+ return nacl.hash(data);
}
exports.sha512 = sha512;
function hmac(digest, blockSize, key, message) {
@@ -8056,18 +6624,16 @@ var talerCrypto = createCommonjsModule(function (module, exports) {
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 __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Native implementation of GNU Taler crypto.
*/
-
-const big_integer_1 = __importDefault(BigInteger);
+const nacl = tslib_1.__importStar(naclFast);
+const big_integer_1 = tslib_1.__importDefault(BigInteger);
function getRandomBytes(n) {
- return naclFast.randomBytes(n);
+ return nacl.randomBytes(n);
}
exports.getRandomBytes = getRandomBytes;
const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
@@ -8166,28 +6732,28 @@ function decodeCrock(encoded) {
}
exports.decodeCrock = decodeCrock;
function eddsaGetPublic(eddsaPriv) {
- const pair = naclFast.sign_keyPair_fromSeed(eddsaPriv);
+ const pair = nacl.sign_keyPair_fromSeed(eddsaPriv);
return pair.publicKey;
}
exports.eddsaGetPublic = eddsaGetPublic;
function ecdheGetPublic(ecdhePriv) {
- return naclFast.scalarMult_base(ecdhePriv);
+ return nacl.scalarMult_base(ecdhePriv);
}
exports.ecdheGetPublic = ecdheGetPublic;
function keyExchangeEddsaEcdhe(eddsaPriv, ecdhePub) {
- const ph = naclFast.hash(eddsaPriv);
+ const ph = nacl.hash(eddsaPriv);
const a = new Uint8Array(32);
for (let i = 0; i < 32; i++) {
a[i] = ph[i];
}
- const x = naclFast.scalarMult(a, ecdhePub);
- return naclFast.hash(x);
+ const x = nacl.scalarMult(a, ecdhePub);
+ return nacl.hash(x);
}
exports.keyExchangeEddsaEcdhe = keyExchangeEddsaEcdhe;
function keyExchangeEcdheEddsa(ecdhePriv, eddsaPub) {
- const curve25519Pub = naclFast.sign_ed25519_pk_to_curve25519(eddsaPub);
- const x = naclFast.scalarMult(ecdhePriv, curve25519Pub);
- return naclFast.hash(x);
+ const curve25519Pub = nacl.sign_ed25519_pk_to_curve25519(eddsaPub);
+ const x = nacl.scalarMult(ecdhePriv, curve25519Pub);
+ return nacl.hash(x);
}
exports.keyExchangeEcdheEddsa = keyExchangeEcdheEddsa;
/**
@@ -8302,36 +6868,36 @@ function rsaVerify(hm, rsaSig, rsaPubEnc) {
}
exports.rsaVerify = rsaVerify;
function createEddsaKeyPair() {
- const eddsaPriv = naclFast.randomBytes(32);
+ const eddsaPriv = nacl.randomBytes(32);
const eddsaPub = eddsaGetPublic(eddsaPriv);
return { eddsaPriv, eddsaPub };
}
exports.createEddsaKeyPair = createEddsaKeyPair;
function createEcdheKeyPair() {
- const ecdhePriv = naclFast.randomBytes(32);
+ const ecdhePriv = nacl.randomBytes(32);
const ecdhePub = ecdheGetPublic(ecdhePriv);
return { ecdhePriv, ecdhePub };
}
exports.createEcdheKeyPair = createEcdheKeyPair;
function createBlindingKeySecret() {
- return naclFast.randomBytes(32);
+ return nacl.randomBytes(32);
}
exports.createBlindingKeySecret = createBlindingKeySecret;
function hash(d) {
- return naclFast.hash(d);
+ return nacl.hash(d);
}
exports.hash = hash;
function eddsaSign(msg, eddsaPriv) {
- const pair = naclFast.sign_keyPair_fromSeed(eddsaPriv);
- return naclFast.sign_detached(msg, pair.secretKey);
+ const pair = nacl.sign_keyPair_fromSeed(eddsaPriv);
+ return nacl.sign_detached(msg, pair.secretKey);
}
exports.eddsaSign = eddsaSign;
function eddsaVerify(msg, sig, eddsaPub) {
- return naclFast.sign_detached_verify(msg, sig, eddsaPub);
+ return nacl.sign_detached_verify(msg, sig, eddsaPub);
}
exports.eddsaVerify = eddsaVerify;
function createHashContext() {
- return new naclFast.HashState();
+ return new nacl.HashState();
}
exports.createHashContext = createHashContext;
function setupRefreshPlanchet(secretSeed, coinNumber) {
@@ -8374,7 +6940,367 @@ var talerCrypto_17 = talerCrypto.eddsaVerify;
var talerCrypto_18 = talerCrypto.createHashContext;
var talerCrypto_19 = talerCrypto.setupRefreshPlanchet;
-var refresh = createCommonjsModule(function (module, exports) {
+var ReserveTransaction = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * @author Florian Dold <dold@taler.net>
+ */
+/**
+ * Imports.
+ */
+
+
+exports.codecForReserveWithdrawTransaction = () => codec.makeCodecForObject()
+ .property("amount", codec.codecForString)
+ .property("h_coin_envelope", codec.codecForString)
+ .property("h_denom_pub", codec.codecForString)
+ .property("reserve_sig", codec.codecForString)
+ .property("type", codec.makeCodecForConstString("WITHDRAW" /* Withdraw */))
+ .property("withdraw_fee", codec.codecForString)
+ .build("ReserveWithdrawTransaction");
+exports.codecForReserveCreditTransaction = () => codec.makeCodecForObject()
+ .property("amount", codec.codecForString)
+ .property("sender_account_url", codec.codecForString)
+ .property("timestamp", time.codecForTimestamp)
+ .property("wire_reference", codec.codecForString)
+ .property("type", codec.makeCodecForConstString("CREDIT" /* Credit */))
+ .build("ReserveCreditTransaction");
+exports.codecForReserveClosingTransaction = () => codec.makeCodecForObject()
+ .property("amount", codec.codecForString)
+ .property("closing_fee", codec.codecForString)
+ .property("exchange_pub", codec.codecForString)
+ .property("exchange_sig", codec.codecForString)
+ .property("h_wire", codec.codecForString)
+ .property("timestamp", time.codecForTimestamp)
+ .property("type", codec.makeCodecForConstString("CLOSING" /* Closing */))
+ .property("wtid", codec.codecForString)
+ .build("ReserveClosingTransaction");
+exports.codecForReserveRecoupTransaction = () => codec.makeCodecForObject()
+ .property("amount", codec.codecForString)
+ .property("coin_pub", codec.codecForString)
+ .property("exchange_pub", codec.codecForString)
+ .property("exchange_sig", codec.codecForString)
+ .property("timestamp", time.codecForTimestamp)
+ .property("type", codec.makeCodecForConstString("RECOUP" /* Recoup */))
+ .build("ReserveRecoupTransaction");
+exports.codecForReserveTransaction = () => codec.makeCodecForUnion()
+ .discriminateOn("type")
+ .alternative("WITHDRAW" /* Withdraw */, exports.codecForReserveWithdrawTransaction())
+ .alternative("CLOSING" /* Closing */, exports.codecForReserveClosingTransaction())
+ .alternative("RECOUP" /* Recoup */, exports.codecForReserveRecoupTransaction())
+ .alternative("CREDIT" /* Credit */, exports.codecForReserveCreditTransaction())
+ .build("ReserveTransaction");
+
+});
+
+unwrapExports(ReserveTransaction);
+var ReserveTransaction_1 = ReserveTransaction.codecForReserveWithdrawTransaction;
+var ReserveTransaction_2 = ReserveTransaction.codecForReserveCreditTransaction;
+var ReserveTransaction_3 = ReserveTransaction.codecForReserveClosingTransaction;
+var ReserveTransaction_4 = ReserveTransaction.codecForReserveRecoupTransaction;
+var ReserveTransaction_5 = ReserveTransaction.codecForReserveTransaction;
+
+var ReserveStatus = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * @author Florian Dold <dold@taler.net>
+ */
+/**
+ * Imports.
+ */
+
+
+exports.codecForReserveStatus = () => codec.makeCodecForObject()
+ .property("balance", codec.codecForString)
+ .property("history", codec.makeCodecForList(ReserveTransaction.codecForReserveTransaction()))
+ .build("ReserveStatus");
+
+});
+
+unwrapExports(ReserveStatus);
+var ReserveStatus_1 = ReserveStatus.codecForReserveStatus;
+
+var reserveHistoryUtil = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+
+const Amounts = tslib_1.__importStar(amounts);
+
+
+/**
+ * Check if two reserve history items (exchange's version) match.
+ */
+function isRemoteHistoryMatch(t1, t2) {
+ switch (t1.type) {
+ case "CLOSING" /* Closing */: {
+ return t1.type === t2.type && t1.wtid == t2.wtid;
+ }
+ case "CREDIT" /* Credit */: {
+ return t1.type === t2.type && t1.wire_reference === t2.wire_reference;
+ }
+ case "RECOUP" /* Recoup */: {
+ return (t1.type === t2.type &&
+ t1.coin_pub === t2.coin_pub &&
+ time.timestampCmp(t1.timestamp, t2.timestamp) === 0);
+ }
+ case "WITHDRAW" /* Withdraw */: {
+ return t1.type === t2.type && t1.h_coin_envelope === t2.h_coin_envelope;
+ }
+ }
+}
+/**
+ * Check a local reserve history item and a remote history item are a match.
+ */
+function isLocalRemoteHistoryMatch(t1, t2) {
+ switch (t1.type) {
+ case "credit" /* Credit */: {
+ return (t2.type === "CREDIT" /* Credit */ &&
+ !!t1.expectedAmount &&
+ Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0);
+ }
+ case "withdraw" /* Withdraw */:
+ return (t2.type === "WITHDRAW" /* Withdraw */ &&
+ !!t1.expectedAmount &&
+ Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0);
+ case "recoup" /* Recoup */: {
+ return (t2.type === "RECOUP" /* Recoup */ &&
+ !!t1.expectedAmount &&
+ Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0);
+ }
+ }
+ return false;
+}
+exports.isLocalRemoteHistoryMatch = isLocalRemoteHistoryMatch;
+/**
+ * Compute totals for the wallet's view of the reserve history.
+ */
+function summarizeReserveHistory(localHistory, currency) {
+ const posAmounts = [];
+ const negAmounts = [];
+ const expectedPosAmounts = [];
+ const expectedNegAmounts = [];
+ const withdrawnAmounts = [];
+ for (const item of localHistory) {
+ switch (item.type) {
+ case "credit" /* Credit */:
+ if (item.matchedExchangeTransaction) {
+ posAmounts.push(Amounts.parseOrThrow(item.matchedExchangeTransaction.amount));
+ }
+ else if (item.expectedAmount) {
+ expectedPosAmounts.push(item.expectedAmount);
+ }
+ break;
+ case "recoup" /* Recoup */:
+ if (item.matchedExchangeTransaction) {
+ if (item.matchedExchangeTransaction) {
+ posAmounts.push(Amounts.parseOrThrow(item.matchedExchangeTransaction.amount));
+ }
+ else if (item.expectedAmount) {
+ expectedPosAmounts.push(item.expectedAmount);
+ }
+ else {
+ throw Error("invariant failed");
+ }
+ }
+ break;
+ case "closing" /* Closing */:
+ if (item.matchedExchangeTransaction) {
+ negAmounts.push(Amounts.parseOrThrow(item.matchedExchangeTransaction.amount));
+ }
+ else {
+ throw Error("invariant failed");
+ }
+ break;
+ case "withdraw" /* Withdraw */:
+ if (item.matchedExchangeTransaction) {
+ negAmounts.push(Amounts.parseOrThrow(item.matchedExchangeTransaction.amount));
+ withdrawnAmounts.push(Amounts.parseOrThrow(item.matchedExchangeTransaction.amount));
+ }
+ else if (item.expectedAmount) {
+ expectedNegAmounts.push(item.expectedAmount);
+ }
+ else {
+ throw Error("invariant failed");
+ }
+ break;
+ }
+ }
+ const z = Amounts.getZero(currency);
+ const computedBalance = Amounts.sub(Amounts.add(z, ...posAmounts).amount, ...negAmounts).amount;
+ const unclaimedReserveAmount = Amounts.sub(Amounts.add(z, ...posAmounts).amount, ...negAmounts, ...expectedNegAmounts).amount;
+ const awaitedReserveAmount = Amounts.sub(Amounts.add(z, ...expectedPosAmounts).amount, ...expectedNegAmounts).amount;
+ const withdrawnAmount = Amounts.add(z, ...withdrawnAmounts).amount;
+ return {
+ computedReserveBalance: computedBalance,
+ unclaimedReserveAmount: unclaimedReserveAmount,
+ awaitedReserveAmount: awaitedReserveAmount,
+ withdrawnAmount,
+ };
+}
+exports.summarizeReserveHistory = summarizeReserveHistory;
+/**
+ * Reconcile the wallet's local model of the reserve history
+ * with the reserve history of the exchange.
+ */
+function reconcileReserveHistory(localHistory, remoteHistory) {
+ const updatedLocalHistory = helpers.deepCopy(localHistory);
+ const newMatchedItems = [];
+ const newAddedItems = [];
+ const remoteMatched = remoteHistory.map(() => false);
+ const localMatched = localHistory.map(() => false);
+ // Take care of deposits
+ // First, see which pairs are already a definite match.
+ for (let remoteIndex = 0; remoteIndex < remoteHistory.length; remoteIndex++) {
+ const rhi = remoteHistory[remoteIndex];
+ for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
+ if (localMatched[localIndex]) {
+ continue;
+ }
+ const lhi = localHistory[localIndex];
+ if (!lhi.matchedExchangeTransaction) {
+ continue;
+ }
+ if (isRemoteHistoryMatch(rhi, lhi.matchedExchangeTransaction)) {
+ localMatched[localIndex] = true;
+ remoteMatched[remoteIndex] = true;
+ break;
+ }
+ }
+ }
+ // Check that all previously matched items are still matched
+ for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
+ if (localMatched[localIndex]) {
+ continue;
+ }
+ const lhi = localHistory[localIndex];
+ if (lhi.matchedExchangeTransaction) {
+ // Don't use for further matching
+ localMatched[localIndex] = true;
+ // FIXME: emit some error here!
+ throw Error("previously matched reserve history item now unmatched");
+ }
+ }
+ // Next, find out if there are any exact new matches between local and remote
+ // history items
+ for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
+ if (localMatched[localIndex]) {
+ continue;
+ }
+ const lhi = localHistory[localIndex];
+ for (let remoteIndex = 0; remoteIndex < remoteHistory.length; remoteIndex++) {
+ const rhi = remoteHistory[remoteIndex];
+ if (remoteMatched[remoteIndex]) {
+ continue;
+ }
+ if (isLocalRemoteHistoryMatch(lhi, rhi)) {
+ localMatched[localIndex] = true;
+ remoteMatched[remoteIndex] = true;
+ updatedLocalHistory[localIndex].matchedExchangeTransaction = rhi;
+ newMatchedItems.push(lhi);
+ break;
+ }
+ }
+ }
+ // Finally we add new history items
+ for (let remoteIndex = 0; remoteIndex < remoteHistory.length; remoteIndex++) {
+ if (remoteMatched[remoteIndex]) {
+ continue;
+ }
+ const rhi = remoteHistory[remoteIndex];
+ let newItem;
+ switch (rhi.type) {
+ case "CLOSING" /* Closing */: {
+ newItem = {
+ type: "closing" /* Closing */,
+ matchedExchangeTransaction: rhi,
+ };
+ break;
+ }
+ case "CREDIT" /* Credit */: {
+ newItem = {
+ type: "credit" /* Credit */,
+ matchedExchangeTransaction: rhi,
+ };
+ break;
+ }
+ case "RECOUP" /* Recoup */: {
+ newItem = {
+ type: "recoup" /* Recoup */,
+ matchedExchangeTransaction: rhi,
+ };
+ break;
+ }
+ case "WITHDRAW" /* Withdraw */: {
+ newItem = {
+ type: "withdraw" /* Withdraw */,
+ matchedExchangeTransaction: rhi,
+ };
+ break;
+ }
+ }
+ updatedLocalHistory.push(newItem);
+ newAddedItems.push(newItem);
+ }
+ return {
+ updatedLocalHistory,
+ newAddedItems,
+ newMatchedItems,
+ };
+}
+exports.reconcileReserveHistory = reconcileReserveHistory;
+
+});
+
+unwrapExports(reserveHistoryUtil);
+var reserveHistoryUtil_1 = reserveHistoryUtil.isLocalRemoteHistoryMatch;
+var reserveHistoryUtil_2 = reserveHistoryUtil.summarizeReserveHistory;
+var reserveHistoryUtil_3 = reserveHistoryUtil.reconcileReserveHistory;
+
+var reserves = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
@@ -8390,24 +7316,651 @@ var refresh = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+const logger = new logging.Logger("reserves.ts");
+function resetReserveRetry(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, (x) => {
+ if (x.retryInfo.active) {
+ x.retryInfo = dbTypes.initRetryInfo();
+ }
+ return x;
+ });
});
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
+}
+/**
+ * Create a reserve, but do not flag it as confirmed yet.
+ *
+ * Adds the corresponding exchange as a trusted exchange if it is neither
+ * audited nor trusted already.
+ */
+function createReserve(ws, req) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const keypair = yield ws.cryptoApi.createEddsaKeypair();
+ const now = time.getTimestampNow();
+ const canonExchange = helpers.canonicalizeBaseUrl(req.exchange);
+ let reserveStatus;
+ if (req.bankWithdrawStatusUrl) {
+ reserveStatus = dbTypes.ReserveRecordStatus.REGISTERING_BANK;
+ }
+ else {
+ reserveStatus = dbTypes.ReserveRecordStatus.UNCONFIRMED;
+ }
+ const reserveRecord = {
+ timestampCreated: now,
+ exchangeBaseUrl: canonExchange,
+ reservePriv: keypair.priv,
+ reservePub: keypair.pub,
+ senderWire: req.senderWire,
+ timestampConfirmed: undefined,
+ timestampReserveInfoPosted: undefined,
+ bankWithdrawStatusUrl: req.bankWithdrawStatusUrl,
+ exchangeWire: req.exchangeWire,
+ reserveStatus,
+ lastSuccessfulStatusQuery: undefined,
+ retryInfo: dbTypes.initRetryInfo(),
+ lastError: undefined,
+ reserveTransactions: [],
+ currency: req.amount.currency,
+ };
+ reserveRecord.reserveTransactions.push({
+ type: "credit" /* Credit */,
+ expectedAmount: req.amount,
+ });
+ const senderWire = req.senderWire;
+ if (senderWire) {
+ const rec = {
+ paytoUri: senderWire,
+ };
+ yield ws.db.put(dbTypes.Stores.senderWires, rec);
+ }
+ const exchangeInfo = yield exchanges.updateExchangeFromUrl(ws, req.exchange);
+ const exchangeDetails = exchangeInfo.details;
+ if (!exchangeDetails) {
+ console.log(exchangeDetails);
+ throw Error("exchange not updated");
+ }
+ const { isAudited, isTrusted } = yield exchanges.getExchangeTrust(ws, exchangeInfo);
+ let currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, exchangeDetails.currency);
+ if (!currencyRecord) {
+ currencyRecord = {
+ auditors: [],
+ exchanges: [],
+ fractionalDigits: 2,
+ name: exchangeDetails.currency,
+ };
+ }
+ if (!isAudited && !isTrusted) {
+ currencyRecord.exchanges.push({
+ baseUrl: req.exchange,
+ exchangePub: exchangeDetails.masterPublicKey,
+ });
+ }
+ const cr = currencyRecord;
+ const resp = yield ws.db.runWithWriteTransaction([dbTypes.Stores.currencies, dbTypes.Stores.reserves, dbTypes.Stores.bankWithdrawUris], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ // Check if we have already created a reserve for that bankWithdrawStatusUrl
+ if (reserveRecord.bankWithdrawStatusUrl) {
+ const bwi = yield tx.get(dbTypes.Stores.bankWithdrawUris, reserveRecord.bankWithdrawStatusUrl);
+ if (bwi) {
+ const otherReserve = yield tx.get(dbTypes.Stores.reserves, bwi.reservePub);
+ if (otherReserve) {
+ logger.trace("returning existing reserve for bankWithdrawStatusUri");
+ return {
+ exchange: otherReserve.exchangeBaseUrl,
+ reservePub: otherReserve.reservePub,
+ };
+ }
+ }
+ yield tx.put(dbTypes.Stores.bankWithdrawUris, {
+ reservePub: reserveRecord.reservePub,
+ talerWithdrawUri: reserveRecord.bankWithdrawStatusUrl,
+ });
+ }
+ yield tx.put(dbTypes.Stores.currencies, cr);
+ yield tx.put(dbTypes.Stores.reserves, reserveRecord);
+ const r = {
+ exchange: canonExchange,
+ reservePub: keypair.pub,
+ };
+ return r;
+ }));
+ ws.notify({ type: "reserve-created" /* ReserveCreated */ });
+ // Asynchronously process the reserve, but return
+ // to the caller already.
+ processReserve(ws, resp.reservePub, true).catch((e) => {
+ console.error("Processing reserve (after createReserve) failed:", e);
+ });
+ return resp;
+ });
+}
+exports.createReserve = createReserve;
+/**
+ * Re-query the status of a reserve.
+ */
+function forceQueryReserve(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.reserves], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield tx.get(dbTypes.Stores.reserves, reservePub);
+ if (!reserve) {
+ return;
+ }
+ // Only force status query where it makes sense
+ switch (reserve.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.DORMANT:
+ case dbTypes.ReserveRecordStatus.WITHDRAWING:
+ case dbTypes.ReserveRecordStatus.QUERYING_STATUS:
+ break;
+ default:
+ return;
+ }
+ reserve.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
+ reserve.retryInfo = dbTypes.initRetryInfo();
+ yield tx.put(dbTypes.Stores.reserves, reserve);
+ }));
+ yield processReserve(ws, reservePub, true);
+ });
+}
+exports.forceQueryReserve = forceQueryReserve;
+/**
+ * First fetch information requred to withdraw from the reserve,
+ * then deplete the reserve, withdrawing coins until it is empty.
+ *
+ * The returned promise resolves once the reserve is set to the
+ * state DORMANT.
+ */
+function processReserve(ws, reservePub, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ return ws.memoProcessReserve.memo(reservePub, () => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const onOpError = (err) => incrementReserveRetry(ws, reservePub, err);
+ yield errors.guardOperationException(() => processReserveImpl(ws, reservePub, forceNow), onOpError);
+ }));
+ });
+}
+exports.processReserve = processReserve;
+function registerReserveWithBank(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ switch (reserve === null || reserve === void 0 ? void 0 : reserve.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
+ break;
+ default:
+ return;
+ }
+ const bankStatusUrl = reserve.bankWithdrawStatusUrl;
+ if (!bankStatusUrl) {
+ return;
+ }
+ console.log("making selection");
+ if (reserve.timestampReserveInfoPosted) {
+ throw Error("bank claims that reserve info selection is not done");
+ }
+ // FIXME: parse bank response
+ yield ws.http.postJson(bankStatusUrl, {
+ reserve_pub: reservePub,
+ selected_exchange: reserve.exchangeWire,
+ });
+ yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, (r) => {
+ switch (r.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ break;
+ default:
+ return;
+ }
+ r.timestampReserveInfoPosted = time.getTimestampNow();
+ r.reserveStatus = dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK;
+ r.retryInfo = dbTypes.initRetryInfo();
+ return r;
+ });
+ ws.notify({ type: "wildcard" /* Wildcard */ });
+ return processReserveBankStatus(ws, reservePub);
+ });
+}
+function processReserveBankStatus(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const onOpError = (err) => incrementReserveRetry(ws, reservePub, err);
+ yield errors.guardOperationException(() => processReserveBankStatusImpl(ws, reservePub), onOpError);
+ });
+}
+exports.processReserveBankStatus = processReserveBankStatus;
+function processReserveBankStatusImpl(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ switch (reserve === null || reserve === void 0 ? void 0 : reserve.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
+ break;
+ default:
+ return;
+ }
+ const bankStatusUrl = reserve.bankWithdrawStatusUrl;
+ if (!bankStatusUrl) {
+ return;
+ }
+ const statusResp = yield ws.http.get(bankStatusUrl);
+ if (statusResp.status !== 200) {
+ throw Error(`unexpected status ${statusResp.status} for bank status query`);
+ }
+ const status = talerTypes.codecForWithdrawOperationStatusResponse().decode(yield statusResp.json());
+ ws.notify({ type: "wildcard" /* Wildcard */ });
+ if (status.selection_done) {
+ if (reserve.reserveStatus === dbTypes.ReserveRecordStatus.REGISTERING_BANK) {
+ yield registerReserveWithBank(ws, reservePub);
+ return yield processReserveBankStatus(ws, reservePub);
+ }
+ }
+ else {
+ yield registerReserveWithBank(ws, reservePub);
+ return yield processReserveBankStatus(ws, reservePub);
+ }
+ if (status.transfer_done) {
+ yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, (r) => {
+ switch (r.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ break;
+ default:
+ return;
+ }
+ const now = time.getTimestampNow();
+ r.timestampConfirmed = now;
+ r.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
+ r.retryInfo = dbTypes.initRetryInfo();
+ return r;
+ });
+ yield processReserveImpl(ws, reservePub, true);
+ }
+ else {
+ yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, (r) => {
+ switch (r.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ break;
+ default:
+ return;
+ }
+ r.bankWithdrawConfirmUrl = status.confirm_transfer_url;
+ return r;
+ });
+ yield incrementReserveRetry(ws, reservePub, undefined);
+ }
+ ws.notify({ type: "wildcard" /* Wildcard */ });
+ });
+}
+function incrementReserveRetry(ws, reservePub, err) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.reserves], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.reserves, reservePub);
+ if (!r) {
+ return;
+ }
+ if (!r.retryInfo) {
+ return;
+ }
+ console.log("updating retry info");
+ console.log("before", r.retryInfo);
+ r.retryInfo.retryCounter++;
+ dbTypes.updateRetryInfoTimeout(r.retryInfo);
+ console.log("after", r.retryInfo);
+ r.lastError = err;
+ yield tx.put(dbTypes.Stores.reserves, r);
+ }));
+ if (err) {
+ ws.notify({
+ type: "reserve-error" /* ReserveOperationError */,
+ operationError: err,
+ });
+ }
+ });
+}
+/**
+ * Update the information about a reserve that is stored in the wallet
+ * by quering the reserve's exchange.
+ */
+function updateReserve(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ if (!reserve) {
+ throw Error("reserve not in db");
+ }
+ if (reserve.timestampConfirmed === undefined) {
+ throw Error("reserve not confirmed yet");
+ }
+ if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.QUERYING_STATUS) {
+ return;
+ }
+ const reqUrl = new URL(`reserves/${reservePub}`, reserve.exchangeBaseUrl);
+ let resp;
+ try {
+ resp = yield ws.http.get(reqUrl.href);
+ console.log("got reserves/${RESERVE_PUB} response", yield resp.json());
+ if (resp.status === 404) {
+ const m = "reserve not known to the exchange yet";
+ throw new errors.OperationFailedError({
+ type: "waiting",
+ message: m,
+ details: {},
+ });
+ }
+ if (resp.status !== 200) {
+ throw Error(`unexpected status code ${resp.status} for reserve/status`);
+ }
+ }
+ catch (e) {
+ logger.trace("caught exception for reserve/status");
+ const m = e.message;
+ const opErr = {
+ type: "network",
+ details: {},
+ message: m,
+ };
+ yield incrementReserveRetry(ws, reservePub, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ const respJson = yield resp.json();
+ const reserveInfo = ReserveStatus.codecForReserveStatus().decode(respJson);
+ const balance = amounts.Amounts.parseOrThrow(reserveInfo.balance);
+ const currency = balance.currency;
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.reserves, dbTypes.Stores.reserveUpdatedEvents], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.reserves, reservePub);
+ if (!r) {
+ return;
+ }
+ if (r.reserveStatus !== dbTypes.ReserveRecordStatus.QUERYING_STATUS) {
+ return;
+ }
+ const newHistoryTransactions = reserveInfo.history.slice(r.reserveTransactions.length);
+ const reserveUpdateId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
+ const reconciled = reserveHistoryUtil.reconcileReserveHistory(r.reserveTransactions, reserveInfo.history);
+ console.log("reconciled history:", JSON.stringify(reconciled, undefined, 2));
+ const summary = reserveHistoryUtil.summarizeReserveHistory(reconciled.updatedLocalHistory, currency);
+ console.log("summary", summary);
+ if (reconciled.newAddedItems.length + reconciled.newMatchedItems.length !=
+ 0) {
+ const reserveUpdate = {
+ reservePub: r.reservePub,
+ timestamp: time.getTimestampNow(),
+ amountReserveBalance: amounts.Amounts.stringify(balance),
+ amountExpected: amounts.Amounts.stringify(summary.awaitedReserveAmount),
+ newHistoryTransactions,
+ reserveUpdateId,
+ };
+ yield tx.put(dbTypes.Stores.reserveUpdatedEvents, reserveUpdate);
+ r.reserveStatus = dbTypes.ReserveRecordStatus.WITHDRAWING;
+ r.retryInfo = dbTypes.initRetryInfo();
+ }
+ else {
+ r.reserveStatus = dbTypes.ReserveRecordStatus.DORMANT;
+ r.retryInfo = dbTypes.initRetryInfo(false);
+ }
+ r.lastSuccessfulStatusQuery = time.getTimestampNow();
+ r.reserveTransactions = reconciled.updatedLocalHistory;
+ r.lastError = undefined;
+ yield tx.put(dbTypes.Stores.reserves, r);
+ }));
+ ws.notify({ type: "reserve-updated" /* ReserveUpdated */ });
+ });
+}
+function processReserveImpl(ws, reservePub, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ if (!reserve) {
+ console.log("not processing reserve: reserve does not exist");
+ return;
+ }
+ if (!forceNow) {
+ const now = time.getTimestampNow();
+ if (reserve.retryInfo.nextRetry.t_ms > now.t_ms) {
+ logger.trace("processReserve retry not due yet");
+ return;
+ }
+ }
+ else {
+ yield resetReserveRetry(ws, reservePub);
+ }
+ logger.trace(`Processing reserve ${reservePub} with status ${reserve.reserveStatus}`);
+ switch (reserve.reserveStatus) {
+ case dbTypes.ReserveRecordStatus.UNCONFIRMED:
+ // nothing to do
+ break;
+ case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
+ yield processReserveBankStatus(ws, reservePub);
+ return yield processReserveImpl(ws, reservePub, true);
+ case dbTypes.ReserveRecordStatus.QUERYING_STATUS:
+ yield updateReserve(ws, reservePub);
+ return yield processReserveImpl(ws, reservePub, true);
+ case dbTypes.ReserveRecordStatus.WITHDRAWING:
+ yield depleteReserve(ws, reservePub);
+ break;
+ case dbTypes.ReserveRecordStatus.DORMANT:
+ // nothing to do
+ break;
+ case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
+ yield processReserveBankStatus(ws, reservePub);
+ break;
+ default:
+ console.warn("unknown reserve record status:", reserve.reserveStatus);
+ assertUnreachable_1.assertUnreachable(reserve.reserveStatus);
+ break;
+ }
+ });
+}
+function confirmReserve(ws, req) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const now = time.getTimestampNow();
+ yield ws.db.mutate(dbTypes.Stores.reserves, req.reservePub, (reserve) => {
+ if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.UNCONFIRMED) {
+ return;
+ }
+ reserve.timestampConfirmed = now;
+ reserve.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
+ reserve.retryInfo = dbTypes.initRetryInfo();
+ return reserve;
+ });
+ ws.notify({ type: "reserve-updated" /* ReserveUpdated */ });
+ processReserve(ws, req.reservePub, true).catch((e) => {
+ console.log("processing reserve (after confirmReserve) failed:", e);
+ });
+ });
+}
+exports.confirmReserve = confirmReserve;
+function makePlanchet(ws, reserve, denom) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield ws.cryptoApi.createPlanchet({
+ denomPub: denom.denomPub,
+ feeWithdraw: denom.feeWithdraw,
+ reservePriv: reserve.reservePriv,
+ reservePub: reserve.reservePub,
+ value: denom.value,
+ });
+ return {
+ blindingKey: r.blindingKey,
+ coinEv: r.coinEv,
+ coinPriv: r.coinPriv,
+ coinPub: r.coinPub,
+ coinValue: r.coinValue,
+ denomPub: r.denomPub,
+ denomPubHash: r.denomPubHash,
+ isFromTip: false,
+ reservePub: r.reservePub,
+ withdrawSig: r.withdrawSig,
+ coinEvHash: r.coinEvHash,
+ };
+ });
+}
+/**
+ * Withdraw coins from a reserve until it is empty.
+ *
+ * When finished, marks the reserve as depleted by setting
+ * the depleted timestamp.
+ */
+function depleteReserve(ws, reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ if (!reserve) {
+ return;
+ }
+ if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.WITHDRAWING) {
+ return;
+ }
+ logger.trace(`depleting reserve ${reservePub}`);
+ const summary = reserveHistoryUtil.summarizeReserveHistory(reserve.reserveTransactions, reserve.currency);
+ const withdrawAmount = summary.unclaimedReserveAmount;
+ logger.trace(`getting denom list`);
+ const denomsForWithdraw = yield withdraw.getVerifiedWithdrawDenomList(ws, reserve.exchangeBaseUrl, withdrawAmount);
+ logger.trace(`got denom list`);
+ if (denomsForWithdraw.length === 0) {
+ // Only complain about inability to withdraw if we
+ // didn't withdraw before.
+ if (amounts.Amounts.isZero(summary.withdrawnAmount)) {
+ const m = `Unable to withdraw from reserve, no denominations are available to withdraw.`;
+ const opErr = {
+ type: "internal",
+ message: m,
+ details: {},
+ };
+ yield incrementReserveRetry(ws, reserve.reservePub, opErr);
+ console.log(m);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ return;
+ }
+ logger.trace("selected denominations");
+ const withdrawalGroupId = talerCrypto.encodeCrock(naclFast.randomBytes(32));
+ const totalCoinValue = amounts.Amounts.sum(denomsForWithdraw.map((x) => x.value))
+ .amount;
+ const planchets = [];
+ for (const d of denomsForWithdraw) {
+ const p = yield makePlanchet(ws, reserve, d);
+ planchets.push(p);
+ }
+ const withdrawalRecord = {
+ withdrawalGroupId: withdrawalGroupId,
+ exchangeBaseUrl: reserve.exchangeBaseUrl,
+ source: {
+ type: "reserve" /* Reserve */,
+ reservePub: reserve.reservePub,
+ },
+ rawWithdrawalAmount: withdrawAmount,
+ timestampStart: time.getTimestampNow(),
+ denoms: denomsForWithdraw.map((x) => x.denomPub),
+ withdrawn: denomsForWithdraw.map((x) => false),
+ planchets,
+ totalCoinValue,
+ retryInfo: dbTypes.initRetryInfo(),
+ lastErrorPerCoin: {},
+ lastError: undefined,
+ };
+ const totalCoinWithdrawFee = amounts.Amounts.sum(denomsForWithdraw.map((x) => x.feeWithdraw)).amount;
+ const totalWithdrawAmount = amounts.Amounts.add(totalCoinValue, totalCoinWithdrawFee)
+ .amount;
+ const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.withdrawalGroups, dbTypes.Stores.reserves], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const newReserve = yield tx.get(dbTypes.Stores.reserves, reservePub);
+ if (!newReserve) {
+ return false;
+ }
+ if (newReserve.reserveStatus !== dbTypes.ReserveRecordStatus.WITHDRAWING) {
+ return false;
+ }
+ const newSummary = reserveHistoryUtil.summarizeReserveHistory(newReserve.reserveTransactions, newReserve.currency);
+ if (amounts.Amounts.cmp(newSummary.unclaimedReserveAmount, totalWithdrawAmount) < 0) {
+ // Something must have happened concurrently!
+ logger.error("aborting withdrawal session, likely concurrent withdrawal happened");
+ return false;
+ }
+ for (let i = 0; i < planchets.length; i++) {
+ const amt = amounts.Amounts.add(denomsForWithdraw[i].value, denomsForWithdraw[i].feeWithdraw).amount;
+ newReserve.reserveTransactions.push({
+ type: "withdraw" /* Withdraw */,
+ expectedAmount: amt,
+ });
+ }
+ newReserve.reserveStatus = dbTypes.ReserveRecordStatus.DORMANT;
+ newReserve.retryInfo = dbTypes.initRetryInfo(false);
+ yield tx.put(dbTypes.Stores.reserves, newReserve);
+ yield tx.put(dbTypes.Stores.withdrawalGroups, withdrawalRecord);
+ return true;
+ }));
+ if (success) {
+ console.log("processing new withdraw group");
+ ws.notify({
+ type: "withdraw-group-created" /* WithdrawGroupCreated */,
+ withdrawalGroupId: withdrawalGroupId,
+ });
+ yield withdraw.processWithdrawGroup(ws, withdrawalGroupId);
+ }
+ else {
+ console.trace("withdraw session already existed");
+ }
+ });
+}
+function createTalerWithdrawReserve(ws, talerWithdrawUri, selectedExchange) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const withdrawInfo = yield withdraw.getBankWithdrawalInfo(ws, talerWithdrawUri);
+ const exchangeWire = yield exchanges.getExchangePaytoUri(ws, selectedExchange, withdrawInfo.wireTypes);
+ const reserve = yield createReserve(ws, {
+ amount: withdrawInfo.amount,
+ bankWithdrawStatusUrl: withdrawInfo.extractedStatusUrl,
+ exchange: selectedExchange,
+ senderWire: withdrawInfo.senderWire,
+ exchangeWire: exchangeWire,
+ });
+ // We do this here, as the reserve should be registered before we return,
+ // so that we can redirect the user to the bank's status page.
+ yield processReserveBankStatus(ws, reserve.reservePub);
+ console.log("acceptWithdrawal: returning");
+ return {
+ reservePub: reserve.reservePub,
+ confirmTransferUrl: withdrawInfo.confirmTransferUrl,
+ };
+ });
+}
+exports.createTalerWithdrawReserve = createTalerWithdrawReserve;
+
+});
+
+unwrapExports(reserves);
+var reserves_1 = reserves.createReserve;
+var reserves_2 = reserves.forceQueryReserve;
+var reserves_3 = reserves.processReserve;
+var reserves_4 = reserves.processReserveBankStatus;
+var reserves_5 = reserves.confirmReserve;
+var reserves_6 = reserves.createTalerWithdrawReserve;
+
+var refresh = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+
@@ -8429,11 +7982,11 @@ const logger = new logging.Logger("refresh.ts");
* to refresh.
*/
function getTotalRefreshCost(denoms, refreshedDenom, amountLeft) {
- const withdrawAmount = Amounts.sub(amountLeft, refreshedDenom.feeRefresh)
+ const withdrawAmount = amounts.Amounts.sub(amountLeft, refreshedDenom.feeRefresh)
.amount;
const withdrawDenoms = withdraw.getWithdrawDenomList(withdrawAmount, denoms);
- const resultingAmount = Amounts.add(Amounts.getZero(withdrawAmount.currency), ...withdrawDenoms.map(d => d.value)).amount;
- const totalCost = Amounts.sub(amountLeft, resultingAmount).amount;
+ const resultingAmount = amounts.Amounts.add(amounts.Amounts.getZero(withdrawAmount.currency), ...withdrawDenoms.map((d) => d.value)).amount;
+ const totalCost = amounts.Amounts.sub(amountLeft, resultingAmount).amount;
logger.trace("total refresh cost for", helpers.amountToPretty(amountLeft), "is", helpers.amountToPretty(totalCost));
return totalCost;
}
@@ -8442,7 +7995,7 @@ exports.getTotalRefreshCost = getTotalRefreshCost;
* Create a refresh session inside a refresh group.
*/
function refreshCreateSession(ws, refreshGroupId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
logger.trace(`creating refresh session for coin ${coinIndex} in refresh group ${refreshGroupId}`);
const refreshGroup = yield ws.db.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!refreshGroup) {
@@ -8474,18 +8027,17 @@ function refreshCreateSession(ws, refreshGroupId, coinIndex) {
const availableDenoms = yield ws.db
.iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl)
.toArray();
- const availableAmount = Amounts.sub(coin.currentAmount, oldDenom.feeRefresh)
+ const availableAmount = amounts.Amounts.sub(coin.currentAmount, oldDenom.feeRefresh)
.amount;
const newCoinDenoms = withdraw.getWithdrawDenomList(availableAmount, availableDenoms);
if (newCoinDenoms.length === 0) {
logger.trace(`not refreshing, available amount ${helpers.amountToPretty(availableAmount)} too small`);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.refreshGroups], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const rg = yield tx.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!rg) {
return;
}
rg.finishedPerCoin[coinIndex] = true;
- rg.finishedPerCoin[coinIndex] = true;
let allDone = true;
for (const f of rg.finishedPerCoin) {
if (!f) {
@@ -8505,18 +8057,18 @@ function refreshCreateSession(ws, refreshGroupId, coinIndex) {
const refreshSession = yield ws.cryptoApi.createRefreshSession(exchange.baseUrl, 3, coin, newCoinDenoms, oldDenom.feeRefresh);
// Store refresh session and subtract refreshed amount from
// coin in the same transaction.
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups, dbTypes.Stores.coins], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups, dbTypes.Stores.coins], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const c = yield tx.get(dbTypes.Stores.coins, coin.coinPub);
if (!c) {
throw Error("coin not found, but marked for refresh");
}
- const r = Amounts.sub(c.currentAmount, refreshSession.amountRefreshInput);
+ const r = amounts.Amounts.sub(c.currentAmount, refreshSession.amountRefreshInput);
if (r.saturated) {
console.log("can't refresh coin, no amount left");
return;
}
c.currentAmount = r.amount;
- c.status = dbTypes.CoinStatus.Dormant;
+ c.status = "dormant" /* Dormant */;
const rg = yield tx.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!rg) {
return;
@@ -8533,7 +8085,7 @@ function refreshCreateSession(ws, refreshGroupId, coinIndex) {
});
}
function refreshMelt(ws, refreshGroupId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const refreshGroup = yield ws.db.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!refreshGroup) {
return;
@@ -8550,14 +8102,14 @@ function refreshMelt(ws, refreshGroupId, coinIndex) {
console.error("can't melt coin, it does not exist");
return;
}
- const reqUrl = new URL("refresh/melt", refreshSession.exchangeBaseUrl);
+ const reqUrl = new URL(`coins/${coin.coinPub}/melt`, refreshSession.exchangeBaseUrl);
const meltReq = {
coin_pub: coin.coinPub,
confirm_sig: refreshSession.confirmSig,
denom_pub_hash: coin.denomPubHash,
denom_sig: coin.denomSig,
rc: refreshSession.hash,
- value_with_fee: Amounts.toString(refreshSession.amountRefreshInput),
+ value_with_fee: amounts.Amounts.stringify(refreshSession.amountRefreshInput),
};
logger.trace(`melt request for coin:`, meltReq);
const resp = yield ws.http.postJson(reqUrl.href, meltReq);
@@ -8583,7 +8135,7 @@ function refreshMelt(ws, refreshGroupId, coinIndex) {
throw Error("invalid response");
}
refreshSession.norevealIndex = norevealIndex;
- yield ws.db.mutate(dbTypes.Stores.refreshGroups, refreshGroupId, rg => {
+ yield ws.db.mutate(dbTypes.Stores.refreshGroups, refreshGroupId, (rg) => {
const rs = rg.refreshSessionPerCoin[coinIndex];
if (!rs) {
return;
@@ -8603,7 +8155,7 @@ function refreshMelt(ws, refreshGroupId, coinIndex) {
});
}
function refreshReveal(ws, refreshGroupId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const refreshGroup = yield ws.db.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!refreshGroup) {
return;
@@ -8640,7 +8192,7 @@ function refreshReveal(ws, refreshGroupId, coinIndex) {
transfer_pub: refreshSession.transferPubs[norevealIndex],
link_sigs: linkSigs,
};
- const reqUrl = new URL("refresh/reveal", refreshSession.exchangeBaseUrl);
+ const reqUrl = new URL(`refreshes/${refreshSession.hash}/reveal`, refreshSession.exchangeBaseUrl);
logger.trace("reveal request:", req);
let resp;
try {
@@ -8672,7 +8224,7 @@ function refreshReveal(ws, refreshGroupId, coinIndex) {
console.error("denom not found");
continue;
}
- const pc = refreshSession.planchetsForGammas[refreshSession.norevealIndex][i];
+ const pc = refreshSession.planchetsForGammas[norevealIndex][i];
const denomSig = yield ws.cryptoApi.rsaUnblind(respJson.ev_sigs[i].ev_sig, pc.blindingKey, denom.denomPub);
const coin = {
blindingKey: pc.blindingKey,
@@ -8683,14 +8235,16 @@ function refreshReveal(ws, refreshGroupId, coinIndex) {
denomPubHash: denom.denomPubHash,
denomSig,
exchangeBaseUrl: refreshSession.exchangeBaseUrl,
- reservePub: undefined,
- status: dbTypes.CoinStatus.Fresh,
- coinIndex: -1,
- withdrawSessionId: "",
+ status: "fresh" /* Fresh */,
+ coinSource: {
+ type: "refresh" /* Refresh */,
+ oldCoinPub: refreshSession.meltCoinPub,
+ },
+ suspended: false,
};
coins.push(coin);
}
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.refreshGroups], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const rg = yield tx.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!rg) {
console.log("no refresh session found");
@@ -8717,7 +8271,7 @@ function refreshReveal(ws, refreshGroupId, coinIndex) {
rg.timestampFinished = time.getTimestampNow();
rg.retryInfo = dbTypes.initRetryInfo(false);
}
- for (let coin of coins) {
+ for (const coin of coins) {
yield tx.put(dbTypes.Stores.coins, coin);
}
yield tx.put(dbTypes.Stores.refreshGroups, rg);
@@ -8729,8 +8283,8 @@ function refreshReveal(ws, refreshGroupId, coinIndex) {
});
}
function incrementRefreshRetry(ws, refreshGroupId, err) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const r = yield tx.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!r) {
return;
@@ -8747,17 +8301,17 @@ function incrementRefreshRetry(ws, refreshGroupId, err) {
});
}
function processRefreshGroup(ws, refreshGroupId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.memoProcessRefresh.memo(refreshGroupId, () => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.memoProcessRefresh.memo(refreshGroupId, () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (e) => incrementRefreshRetry(ws, refreshGroupId, e);
- return yield errors.guardOperationException(() => __awaiter(this, void 0, void 0, function* () { return yield processRefreshGroupImpl(ws, refreshGroupId, forceNow); }), onOpErr);
+ return yield errors.guardOperationException(() => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield processRefreshGroupImpl(ws, refreshGroupId, forceNow); }), onOpErr);
}));
});
}
exports.processRefreshGroup = processRefreshGroup;
function resetRefreshGroupRetry(ws, refreshSessionId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.refreshGroups, refreshSessionId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.refreshGroups, refreshSessionId, (x) => {
if (x.retryInfo.active) {
x.retryInfo = dbTypes.initRetryInfo();
}
@@ -8766,7 +8320,7 @@ function resetRefreshGroupRetry(ws, refreshSessionId) {
});
}
function processRefreshGroupImpl(ws, refreshGroupId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetRefreshGroupRetry(ws, refreshGroupId);
}
@@ -8783,7 +8337,7 @@ function processRefreshGroupImpl(ws, refreshGroupId, forceNow) {
});
}
function processRefreshSession(ws, refreshGroupId, coinIndex) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
logger.trace(`processing refresh session for coin ${coinIndex} of group ${refreshGroupId}`);
let refreshGroup = yield ws.db.get(dbTypes.Stores.refreshGroups, refreshGroupId);
if (!refreshGroup) {
@@ -8816,17 +8370,17 @@ function processRefreshSession(ws, refreshGroupId, coinIndex) {
* Create a refresh group for a list of coins.
*/
function createRefreshGroup(tx, oldCoinPubs, reason) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const refreshGroupId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
const refreshGroup = {
timestampFinished: undefined,
- finishedPerCoin: oldCoinPubs.map(x => false),
+ finishedPerCoin: oldCoinPubs.map((x) => false),
lastError: undefined,
lastErrorPerCoin: {},
- oldCoinPubs: oldCoinPubs.map(x => x.coinPub),
+ oldCoinPubs: oldCoinPubs.map((x) => x.coinPub),
reason,
refreshGroupId,
- refreshSessionPerCoin: oldCoinPubs.map(x => undefined),
+ refreshSessionPerCoin: oldCoinPubs.map((x) => undefined),
retryInfo: dbTypes.initRetryInfo(),
};
yield tx.put(dbTypes.Stores.refreshGroups, refreshGroup);
@@ -8844,6 +8398,1232 @@ var refresh_1 = refresh.getTotalRefreshCost;
var refresh_2 = refresh.processRefreshGroup;
var refresh_3 = refresh.createRefreshGroup;
+var recoup = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+
+
+
+
+
+
+
+function incrementRecoupRetry(ws, recoupGroupId, err) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.recoupGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!r) {
+ return;
+ }
+ if (!r.retryInfo) {
+ return;
+ }
+ r.retryInfo.retryCounter++;
+ dbTypes.updateRetryInfoTimeout(r.retryInfo);
+ r.lastError = err;
+ yield tx.put(dbTypes.Stores.recoupGroups, r);
+ }));
+ ws.notify({ type: "recoup-operation-error" /* RecoupOperationError */ });
+ });
+}
+function putGroupAsFinished(ws, tx, recoupGroup, coinIdx) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ if (recoupGroup.timestampFinished) {
+ return;
+ }
+ recoupGroup.recoupFinishedPerCoin[coinIdx] = true;
+ let allFinished = true;
+ for (const b of recoupGroup.recoupFinishedPerCoin) {
+ if (!b) {
+ allFinished = false;
+ }
+ }
+ if (allFinished) {
+ recoupGroup.timestampFinished = time.getTimestampNow();
+ recoupGroup.retryInfo = dbTypes.initRetryInfo(false);
+ recoupGroup.lastError = undefined;
+ if (recoupGroup.scheduleRefreshCoins.length > 0) {
+ const refreshGroupId = yield refresh.createRefreshGroup(tx, recoupGroup.scheduleRefreshCoins.map((x) => ({ coinPub: x })), "recoup" /* Recoup */);
+ refresh.processRefreshGroup(ws, refreshGroupId.refreshGroupId).then((e) => {
+ console.error("error while refreshing after recoup", e);
+ });
+ }
+ }
+ yield tx.put(dbTypes.Stores.recoupGroups, recoupGroup);
+ });
+}
+function recoupTipCoin(ws, recoupGroupId, coinIdx, coin) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ // We can't really recoup a coin we got via tipping.
+ // Thus we just put the coin to sleep.
+ // FIXME: somehow report this to the user
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.recoupGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const recoupGroup = yield tx.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!recoupGroup) {
+ return;
+ }
+ if (recoupGroup.recoupFinishedPerCoin[coinIdx]) {
+ return;
+ }
+ yield putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
+ }));
+ });
+}
+function recoupWithdrawCoin(ws, recoupGroupId, coinIdx, coin, cs) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reservePub = cs.reservePub;
+ const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
+ if (!reserve) {
+ // FIXME: We should at least emit some pending operation / warning for this?
+ return;
+ }
+ ws.notify({
+ type: "recoup-started" /* RecoupStarted */,
+ });
+ const recoupRequest = yield ws.cryptoApi.createRecoupRequest(coin);
+ const reqUrl = new URL(`/coins/${coin.coinPub}/recoup`, coin.exchangeBaseUrl);
+ const resp = yield ws.http.postJson(reqUrl.href, recoupRequest);
+ const recoupConfirmation = yield errors.scrutinizeTalerJsonResponse(resp, talerTypes.codecForRecoupConfirmation());
+ if (recoupConfirmation.reserve_pub !== reservePub) {
+ throw Error(`Coin's reserve doesn't match reserve on recoup`);
+ }
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, coin.exchangeBaseUrl);
+ if (!exchange) {
+ // FIXME: report inconsistency?
+ return;
+ }
+ const exchangeDetails = exchange.details;
+ if (!exchangeDetails) {
+ // FIXME: report inconsistency?
+ return;
+ }
+ // FIXME: verify that our expectations about the amount match
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.reserves, dbTypes.Stores.recoupGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const recoupGroup = yield tx.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!recoupGroup) {
+ return;
+ }
+ if (recoupGroup.recoupFinishedPerCoin[coinIdx]) {
+ return;
+ }
+ const updatedCoin = yield tx.get(dbTypes.Stores.coins, coin.coinPub);
+ if (!updatedCoin) {
+ return;
+ }
+ const updatedReserve = yield tx.get(dbTypes.Stores.reserves, reserve.reservePub);
+ if (!updatedReserve) {
+ return;
+ }
+ updatedCoin.status = "dormant" /* Dormant */;
+ const currency = updatedCoin.currentAmount.currency;
+ updatedCoin.currentAmount = amounts.Amounts.getZero(currency);
+ updatedReserve.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
+ yield tx.put(dbTypes.Stores.coins, updatedCoin);
+ yield tx.put(dbTypes.Stores.reserves, updatedReserve);
+ yield putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
+ }));
+ ws.notify({
+ type: "recoup-finished" /* RecoupFinished */,
+ });
+ reserves.forceQueryReserve(ws, reserve.reservePub).catch((e) => {
+ console.log("re-querying reserve after recoup failed:", e);
+ });
+ });
+}
+function recoupRefreshCoin(ws, recoupGroupId, coinIdx, coin, cs) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ ws.notify({
+ type: "recoup-started" /* RecoupStarted */,
+ });
+ const recoupRequest = yield ws.cryptoApi.createRecoupRequest(coin);
+ const reqUrl = new URL(`/coins/${coin.coinPub}/recoup`, coin.exchangeBaseUrl);
+ console.log("making recoup request");
+ const resp = yield ws.http.postJson(reqUrl.href, recoupRequest);
+ const recoupConfirmation = yield errors.scrutinizeTalerJsonResponse(resp, talerTypes.codecForRecoupConfirmation());
+ if (recoupConfirmation.old_coin_pub != cs.oldCoinPub) {
+ throw Error(`Coin's oldCoinPub doesn't match reserve on recoup`);
+ }
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, coin.exchangeBaseUrl);
+ if (!exchange) {
+ // FIXME: report inconsistency?
+ return;
+ }
+ const exchangeDetails = exchange.details;
+ if (!exchangeDetails) {
+ // FIXME: report inconsistency?
+ return;
+ }
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.reserves, dbTypes.Stores.recoupGroups, dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const recoupGroup = yield tx.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!recoupGroup) {
+ return;
+ }
+ if (recoupGroup.recoupFinishedPerCoin[coinIdx]) {
+ return;
+ }
+ const oldCoin = yield tx.get(dbTypes.Stores.coins, cs.oldCoinPub);
+ const revokedCoin = yield tx.get(dbTypes.Stores.coins, coin.coinPub);
+ if (!revokedCoin) {
+ return;
+ }
+ if (!oldCoin) {
+ return;
+ }
+ revokedCoin.status = "dormant" /* Dormant */;
+ oldCoin.currentAmount = amounts.Amounts.add(oldCoin.currentAmount, recoupGroup.oldAmountPerCoin[coinIdx]).amount;
+ console.log("recoup: setting old coin amount to", amounts.Amounts.stringify(oldCoin.currentAmount));
+ recoupGroup.scheduleRefreshCoins.push(oldCoin.coinPub);
+ yield tx.put(dbTypes.Stores.coins, revokedCoin);
+ yield tx.put(dbTypes.Stores.coins, oldCoin);
+ yield putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
+ }));
+ });
+}
+function resetRecoupGroupRetry(ws, recoupGroupId) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.recoupGroups, recoupGroupId, (x) => {
+ if (x.retryInfo.active) {
+ x.retryInfo = dbTypes.initRetryInfo();
+ }
+ return x;
+ });
+ });
+}
+function processRecoupGroup(ws, recoupGroupId, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.memoProcessRecoup.memo(recoupGroupId, () => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const onOpErr = (e) => incrementRecoupRetry(ws, recoupGroupId, e);
+ return yield errors.guardOperationException(() => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield processRecoupGroupImpl(ws, recoupGroupId, forceNow); }), onOpErr);
+ }));
+ });
+}
+exports.processRecoupGroup = processRecoupGroup;
+function processRecoupGroupImpl(ws, recoupGroupId, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ if (forceNow) {
+ yield resetRecoupGroupRetry(ws, recoupGroupId);
+ }
+ console.log("in processRecoupGroupImpl");
+ const recoupGroup = yield ws.db.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!recoupGroup) {
+ return;
+ }
+ console.log(recoupGroup);
+ if (recoupGroup.timestampFinished) {
+ console.log("recoup group finished");
+ return;
+ }
+ const ps = recoupGroup.coinPubs.map((x, i) => processRecoup(ws, recoupGroupId, i));
+ yield Promise.all(ps);
+ });
+}
+function createRecoupGroup(ws, tx, coinPubs) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const recoupGroupId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
+ const recoupGroup = {
+ recoupGroupId,
+ coinPubs: coinPubs,
+ lastError: undefined,
+ timestampFinished: undefined,
+ timestampStarted: time.getTimestampNow(),
+ retryInfo: dbTypes.initRetryInfo(),
+ recoupFinishedPerCoin: coinPubs.map(() => false),
+ // Will be populated later
+ oldAmountPerCoin: [],
+ scheduleRefreshCoins: [],
+ };
+ for (let coinIdx = 0; coinIdx < coinPubs.length; coinIdx++) {
+ const coinPub = coinPubs[coinIdx];
+ const coin = yield tx.get(dbTypes.Stores.coins, coinPub);
+ if (!coin) {
+ yield putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
+ continue;
+ }
+ if (amounts.Amounts.isZero(coin.currentAmount)) {
+ yield putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
+ continue;
+ }
+ recoupGroup.oldAmountPerCoin[coinIdx] = coin.currentAmount;
+ coin.currentAmount = amounts.Amounts.getZero(coin.currentAmount.currency);
+ yield tx.put(dbTypes.Stores.coins, coin);
+ }
+ yield tx.put(dbTypes.Stores.recoupGroups, recoupGroup);
+ return recoupGroupId;
+ });
+}
+exports.createRecoupGroup = createRecoupGroup;
+function processRecoup(ws, recoupGroupId, coinIdx) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const recoupGroup = yield ws.db.get(dbTypes.Stores.recoupGroups, recoupGroupId);
+ if (!recoupGroup) {
+ return;
+ }
+ if (recoupGroup.timestampFinished) {
+ return;
+ }
+ if (recoupGroup.recoupFinishedPerCoin[coinIdx]) {
+ return;
+ }
+ const coinPub = recoupGroup.coinPubs[coinIdx];
+ const coin = yield ws.db.get(dbTypes.Stores.coins, coinPub);
+ if (!coin) {
+ throw Error(`Coin ${coinPub} not found, can't request payback`);
+ }
+ const cs = coin.coinSource;
+ switch (cs.type) {
+ case "tip" /* Tip */:
+ return recoupTipCoin(ws, recoupGroupId, coinIdx);
+ case "refresh" /* Refresh */:
+ return recoupRefreshCoin(ws, recoupGroupId, coinIdx, coin, cs);
+ case "withdraw" /* Withdraw */:
+ return recoupWithdrawCoin(ws, recoupGroupId, coinIdx, coin, cs);
+ default:
+ throw Error("unknown coin source type");
+ }
+ });
+}
+
+});
+
+unwrapExports(recoup);
+var recoup_1 = recoup.processRecoupGroup;
+var recoup_2 = recoup.createRecoupGroup;
+
+var exchanges = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+
+
+const Amounts = tslib_1.__importStar(amounts);
+
+
+
+
+
+
+function denominationRecordFromKeys(ws, exchangeBaseUrl, denomIn) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const denomPubHash = yield ws.cryptoApi.hashEncoded(denomIn.denom_pub);
+ const d = {
+ denomPub: denomIn.denom_pub,
+ denomPubHash,
+ exchangeBaseUrl,
+ feeDeposit: Amounts.parseOrThrow(denomIn.fee_deposit),
+ feeRefresh: Amounts.parseOrThrow(denomIn.fee_refresh),
+ feeRefund: Amounts.parseOrThrow(denomIn.fee_refund),
+ feeWithdraw: Amounts.parseOrThrow(denomIn.fee_withdraw),
+ isOffered: true,
+ isRevoked: false,
+ masterSig: denomIn.master_sig,
+ stampExpireDeposit: denomIn.stamp_expire_deposit,
+ stampExpireLegal: denomIn.stamp_expire_legal,
+ stampExpireWithdraw: denomIn.stamp_expire_withdraw,
+ stampStart: denomIn.stamp_start,
+ status: dbTypes.DenominationStatus.Unverified,
+ value: Amounts.parseOrThrow(denomIn.value),
+ };
+ return d;
+ });
+}
+function setExchangeError(ws, baseUrl, err) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ console.log(`last error for exchange ${baseUrl}:`, err);
+ const mut = (exchange) => {
+ exchange.lastError = err;
+ return exchange;
+ };
+ yield ws.db.mutate(dbTypes.Stores.exchanges, baseUrl, mut);
+ });
+}
+/**
+ * Fetch the exchange's /keys and update our database accordingly.
+ *
+ * Exceptions thrown in this method must be caught and reported
+ * in the pending operations.
+ */
+function updateExchangeWithKeys(ws, baseUrl) {
+ var _a;
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const existingExchangeRecord = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
+ if ((existingExchangeRecord === null || existingExchangeRecord === void 0 ? void 0 : existingExchangeRecord.updateStatus) != "fetch-keys" /* FetchKeys */) {
+ return;
+ }
+ const keysUrl = new URL("keys", baseUrl);
+ keysUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
+ let keysResp;
+ try {
+ const r = yield ws.http.get(keysUrl.href);
+ if (r.status !== 200) {
+ throw Error(`unexpected status for keys: ${r.status}`);
+ }
+ keysResp = yield r.json();
+ }
+ catch (e) {
+ const m = `Fetching keys failed: ${e.message}`;
+ const opErr = {
+ type: "network",
+ details: {
+ requestUrl: (_a = e.config) === null || _a === void 0 ? void 0 : _a.url,
+ },
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ let exchangeKeysJson;
+ try {
+ exchangeKeysJson = talerTypes.codecForExchangeKeysJson().decode(keysResp);
+ }
+ catch (e) {
+ const m = `Parsing /keys response failed: ${e.message}`;
+ const opErr = {
+ type: "protocol-violation",
+ details: {},
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ const lastUpdateTimestamp = exchangeKeysJson.list_issue_date;
+ if (!lastUpdateTimestamp) {
+ const m = `Parsing /keys response failed: invalid list_issue_date.`;
+ const opErr = {
+ type: "protocol-violation",
+ details: {},
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ if (exchangeKeysJson.denoms.length === 0) {
+ const m = "exchange doesn't offer any denominations";
+ const opErr = {
+ type: "protocol-violation",
+ details: {},
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ const protocolVersion = exchangeKeysJson.version;
+ if (!protocolVersion) {
+ const m = "outdate exchange, no version in /keys response";
+ const opErr = {
+ type: "protocol-violation",
+ details: {},
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ const versionRes = libtoolVersion.compare(versions.WALLET_EXCHANGE_PROTOCOL_VERSION, protocolVersion);
+ if ((versionRes === null || versionRes === void 0 ? void 0 : versionRes.compatible) != true) {
+ const m = "exchange protocol version not compatible with wallet";
+ const opErr = {
+ type: "protocol-incompatible",
+ details: {
+ exchangeProtocolVersion: protocolVersion,
+ walletProtocolVersion: versions.WALLET_EXCHANGE_PROTOCOL_VERSION,
+ },
+ message: m,
+ };
+ yield setExchangeError(ws, baseUrl, opErr);
+ throw new errors.OperationFailedAndReportedError(opErr);
+ }
+ const currency = Amounts.parseOrThrow(exchangeKeysJson.denoms[0].value)
+ .currency;
+ const newDenominations = yield Promise.all(exchangeKeysJson.denoms.map((d) => denominationRecordFromKeys(ws, baseUrl, d)));
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges, dbTypes.Stores.denominations, dbTypes.Stores.recoupGroups, dbTypes.Stores.coins], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ var _b;
+ const r = yield tx.get(dbTypes.Stores.exchanges, baseUrl);
+ if (!r) {
+ console.warn(`exchange ${baseUrl} no longer present`);
+ return;
+ }
+ if (r.details) ;
+ // FIXME: validate signing keys and merge with old set
+ r.details = {
+ auditors: exchangeKeysJson.auditors,
+ currency: currency,
+ lastUpdateTime: lastUpdateTimestamp,
+ masterPublicKey: exchangeKeysJson.master_public_key,
+ protocolVersion: protocolVersion,
+ signingKeys: exchangeKeysJson.signkeys,
+ };
+ r.updateStatus = "fetch-wire" /* FetchWire */;
+ r.lastError = undefined;
+ yield tx.put(dbTypes.Stores.exchanges, r);
+ for (const newDenom of newDenominations) {
+ const oldDenom = yield tx.get(dbTypes.Stores.denominations, [
+ baseUrl,
+ newDenom.denomPub,
+ ]);
+ if (oldDenom) ;
+ else {
+ yield tx.put(dbTypes.Stores.denominations, newDenom);
+ }
+ }
+ // Handle recoup
+ const recoupDenomList = (_b = exchangeKeysJson.recoup) !== null && _b !== void 0 ? _b : [];
+ const newlyRevokedCoinPubs = [];
+ console.log("recoup list from exchange", recoupDenomList);
+ for (const recoupInfo of recoupDenomList) {
+ const oldDenom = yield tx.getIndexed(dbTypes.Stores.denominations.denomPubHashIndex, recoupInfo.h_denom_pub);
+ if (!oldDenom) {
+ // We never even knew about the revoked denomination, all good.
+ continue;
+ }
+ if (oldDenom.isRevoked) {
+ // We already marked the denomination as revoked,
+ // this implies we revoked all coins
+ console.log("denom already revoked");
+ continue;
+ }
+ console.log("revoking denom", recoupInfo.h_denom_pub);
+ oldDenom.isRevoked = true;
+ yield tx.put(dbTypes.Stores.denominations, oldDenom);
+ const affectedCoins = yield tx
+ .iterIndexed(dbTypes.Stores.coins.denomPubHashIndex, recoupInfo.h_denom_pub)
+ .toArray();
+ for (const ac of affectedCoins) {
+ newlyRevokedCoinPubs.push(ac.coinPub);
+ }
+ }
+ if (newlyRevokedCoinPubs.length != 0) {
+ console.log("recouping coins", newlyRevokedCoinPubs);
+ yield recoup.createRecoupGroup(ws, tx, newlyRevokedCoinPubs);
+ }
+ }));
+ });
+}
+function updateExchangeFinalize(ws, exchangeBaseUrl) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!exchange) {
+ return;
+ }
+ if (exchange.updateStatus != "finalize-update" /* FinalizeUpdate */) {
+ return;
+ }
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges, dbTypes.Stores.exchangeUpdatedEvents], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!r) {
+ return;
+ }
+ if (r.updateStatus != "finalize-update" /* FinalizeUpdate */) {
+ return;
+ }
+ r.updateStatus = "finished" /* Finished */;
+ yield tx.put(dbTypes.Stores.exchanges, r);
+ const updateEvent = {
+ exchangeBaseUrl: exchange.baseUrl,
+ timestamp: time.getTimestampNow(),
+ };
+ yield tx.put(dbTypes.Stores.exchangeUpdatedEvents, updateEvent);
+ }));
+ });
+}
+function updateExchangeWithTermsOfService(ws, exchangeBaseUrl) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!exchange) {
+ return;
+ }
+ if (exchange.updateStatus != "fetch-terms" /* FetchTerms */) {
+ return;
+ }
+ const reqUrl = new URL("terms", exchangeBaseUrl);
+ reqUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
+ const headers = {
+ Accept: "text/plain",
+ };
+ const resp = yield ws.http.get(reqUrl.href, { headers });
+ if (resp.status !== 200) {
+ throw Error(`/terms response has unexpected status code (${resp.status})`);
+ }
+ const tosText = yield resp.text();
+ const tosEtag = resp.headers.get("etag") || undefined;
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!r) {
+ return;
+ }
+ if (r.updateStatus != "fetch-terms" /* FetchTerms */) {
+ return;
+ }
+ r.termsOfServiceText = tosText;
+ r.termsOfServiceLastEtag = tosEtag;
+ r.updateStatus = "finalize-update" /* FinalizeUpdate */;
+ yield tx.put(dbTypes.Stores.exchanges, r);
+ }));
+ });
+}
+function acceptExchangeTermsOfService(ws, exchangeBaseUrl, etag) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!r) {
+ return;
+ }
+ r.termsOfServiceAcceptedEtag = etag;
+ r.termsOfServiceAcceptedTimestamp = time.getTimestampNow();
+ yield tx.put(dbTypes.Stores.exchanges, r);
+ }));
+ });
+}
+exports.acceptExchangeTermsOfService = acceptExchangeTermsOfService;
+/**
+ * Fetch wire information for an exchange and store it in the database.
+ *
+ * @param exchangeBaseUrl Exchange base URL, assumed to be already normalized.
+ */
+function updateExchangeWithWireInfo(ws, exchangeBaseUrl) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!exchange) {
+ return;
+ }
+ if (exchange.updateStatus != "fetch-wire" /* FetchWire */) {
+ return;
+ }
+ const details = exchange.details;
+ if (!details) {
+ throw Error("invalid exchange state");
+ }
+ const reqUrl = new URL("wire", exchangeBaseUrl);
+ reqUrl.searchParams.set("cacheBreaker", versions.WALLET_CACHE_BREAKER_CLIENT_VERSION);
+ const resp = yield ws.http.get(reqUrl.href);
+ if (resp.status !== 200) {
+ throw Error(`/wire response has unexpected status code (${resp.status})`);
+ }
+ const wiJson = yield resp.json();
+ if (!wiJson) {
+ throw Error("/wire response malformed");
+ }
+ const wireInfo = talerTypes.codecForExchangeWireJson().decode(wiJson);
+ for (const a of wireInfo.accounts) {
+ console.log("validating exchange acct");
+ const isValid = yield ws.cryptoApi.isValidWireAccount(a.payto_uri, a.master_sig, details.masterPublicKey);
+ if (!isValid) {
+ throw Error("exchange acct signature invalid");
+ }
+ }
+ const feesForType = {};
+ for (const wireMethod of Object.keys(wireInfo.fees)) {
+ const feeList = [];
+ for (const x of wireInfo.fees[wireMethod]) {
+ const startStamp = x.start_date;
+ const endStamp = x.end_date;
+ const fee = {
+ closingFee: Amounts.parseOrThrow(x.closing_fee),
+ endStamp,
+ sig: x.sig,
+ startStamp,
+ wireFee: Amounts.parseOrThrow(x.wire_fee),
+ };
+ const isValid = yield ws.cryptoApi.isValidWireFee(wireMethod, fee, details.masterPublicKey);
+ if (!isValid) {
+ throw Error("exchange wire fee signature invalid");
+ }
+ feeList.push(fee);
+ }
+ feesForType[wireMethod] = feeList;
+ }
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const r = yield tx.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!r) {
+ return;
+ }
+ if (r.updateStatus != "fetch-wire" /* FetchWire */) {
+ return;
+ }
+ r.wireInfo = {
+ accounts: wireInfo.accounts,
+ feesForType: feesForType,
+ };
+ r.updateStatus = "fetch-terms" /* FetchTerms */;
+ r.lastError = undefined;
+ yield tx.put(dbTypes.Stores.exchanges, r);
+ }));
+ });
+}
+function updateExchangeFromUrl(ws, baseUrl, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const onOpErr = (e) => setExchangeError(ws, baseUrl, e);
+ return yield errors.guardOperationException(() => updateExchangeFromUrlImpl(ws, baseUrl, forceNow), onOpErr);
+ });
+}
+exports.updateExchangeFromUrl = updateExchangeFromUrl;
+/**
+ * Update or add exchange DB entry by fetching the /keys and /wire information.
+ * Optionally link the reserve entry to the new or existing
+ * exchange entry in then DB.
+ */
+function updateExchangeFromUrlImpl(ws, baseUrl, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const now = time.getTimestampNow();
+ baseUrl = helpers.canonicalizeBaseUrl(baseUrl);
+ const r = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
+ if (!r) {
+ const newExchangeRecord = {
+ builtIn: false,
+ baseUrl: baseUrl,
+ details: undefined,
+ wireInfo: undefined,
+ updateStatus: "fetch-keys" /* FetchKeys */,
+ updateStarted: now,
+ updateReason: "initial" /* Initial */,
+ timestampAdded: time.getTimestampNow(),
+ termsOfServiceAcceptedEtag: undefined,
+ termsOfServiceAcceptedTimestamp: undefined,
+ termsOfServiceLastEtag: undefined,
+ termsOfServiceText: undefined,
+ updateDiff: undefined,
+ };
+ yield ws.db.put(dbTypes.Stores.exchanges, newExchangeRecord);
+ }
+ else {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.exchanges], (t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const rec = yield t.get(dbTypes.Stores.exchanges, baseUrl);
+ if (!rec) {
+ return;
+ }
+ if (rec.updateStatus != "fetch-keys" /* FetchKeys */ && !forceNow) {
+ return;
+ }
+ if (rec.updateStatus != "fetch-keys" /* FetchKeys */ && forceNow) {
+ rec.updateReason = "forced" /* Forced */;
+ }
+ rec.updateStarted = now;
+ rec.updateStatus = "fetch-keys" /* FetchKeys */;
+ rec.lastError = undefined;
+ t.put(dbTypes.Stores.exchanges, rec);
+ }));
+ }
+ yield updateExchangeWithKeys(ws, baseUrl);
+ yield updateExchangeWithWireInfo(ws, baseUrl);
+ yield updateExchangeWithTermsOfService(ws, baseUrl);
+ yield updateExchangeFinalize(ws, baseUrl);
+ const updatedExchange = yield ws.db.get(dbTypes.Stores.exchanges, baseUrl);
+ if (!updatedExchange) {
+ // This should practically never happen
+ throw Error("exchange not found");
+ }
+ return updatedExchange;
+ });
+}
+/**
+ * Check if and how an exchange is trusted and/or audited.
+ */
+function getExchangeTrust(ws, exchangeInfo) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ let isTrusted = false;
+ let isAudited = false;
+ const exchangeDetails = exchangeInfo.details;
+ if (!exchangeDetails) {
+ throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
+ }
+ const currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, exchangeDetails.currency);
+ if (currencyRecord) {
+ for (const trustedExchange of currencyRecord.exchanges) {
+ if (trustedExchange.exchangePub === exchangeDetails.masterPublicKey) {
+ isTrusted = true;
+ break;
+ }
+ }
+ for (const trustedAuditor of currencyRecord.auditors) {
+ for (const exchangeAuditor of exchangeDetails.auditors) {
+ if (trustedAuditor.auditorPub === exchangeAuditor.auditor_pub) {
+ isAudited = true;
+ break;
+ }
+ }
+ }
+ }
+ return { isTrusted, isAudited };
+ });
+}
+exports.getExchangeTrust = getExchangeTrust;
+function getExchangePaytoUri(ws, exchangeBaseUrl, supportedTargetTypes) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ // We do the update here, since the exchange might not even exist
+ // yet in our database.
+ const exchangeRecord = yield updateExchangeFromUrl(ws, exchangeBaseUrl);
+ if (!exchangeRecord) {
+ throw Error(`Exchange '${exchangeBaseUrl}' not found.`);
+ }
+ const exchangeWireInfo = exchangeRecord.wireInfo;
+ if (!exchangeWireInfo) {
+ throw Error(`Exchange wire info for '${exchangeBaseUrl}' not found.`);
+ }
+ for (const account of exchangeWireInfo.accounts) {
+ const res = payto.parsePaytoUri(account.payto_uri);
+ if (!res) {
+ continue;
+ }
+ if (supportedTargetTypes.includes(res.targetType)) {
+ return account.payto_uri;
+ }
+ }
+ throw Error("no matching exchange account found");
+ });
+}
+exports.getExchangePaytoUri = getExchangePaytoUri;
+
+});
+
+unwrapExports(exchanges);
+var exchanges_1 = exchanges.acceptExchangeTermsOfService;
+var exchanges_2 = exchanges.updateExchangeFromUrl;
+var exchanges_3 = exchanges.getExchangeTrust;
+var exchanges_4 = exchanges.getExchangePaytoUri;
+
+var withdraw = createCommonjsModule(function (module, exports) {
+/*
+ This file is part of GNU Taler
+ (C) 2019-2029 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/>
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+const Amounts = tslib_1.__importStar(amounts);
+
+
+
+
+
+const LibtoolVersion = tslib_1.__importStar(libtoolVersion);
+
+
+const logger = new logging.Logger("withdraw.ts");
+function isWithdrawableDenom(d) {
+ const now = time.getTimestampNow();
+ const started = time.timestampCmp(now, d.stampStart) >= 0;
+ const lastPossibleWithdraw = time.timestampSubtractDuraction(d.stampExpireWithdraw, { d_ms: 50 * 1000 });
+ const remaining = time.getDurationRemaining(lastPossibleWithdraw, now);
+ const stillOkay = remaining.d_ms !== 0;
+ return started && stillOkay && !d.isRevoked;
+}
+/**
+ * Get a list of denominations (with repetitions possible)
+ * whose total value is as close as possible to the available
+ * amount, but never larger.
+ */
+function getWithdrawDenomList(amountAvailable, denoms) {
+ let remaining = Amounts.copy(amountAvailable);
+ const ds = [];
+ denoms = denoms.filter(isWithdrawableDenom);
+ denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value));
+ // This is an arbitrary number of coins
+ // we can withdraw in one go. It's not clear if this limit
+ // is useful ...
+ for (let i = 0; i < 1000; i++) {
+ let found = false;
+ for (const d of denoms) {
+ const cost = Amounts.add(d.value, d.feeWithdraw).amount;
+ if (Amounts.cmp(remaining, cost) < 0) {
+ continue;
+ }
+ found = true;
+ remaining = Amounts.sub(remaining, cost).amount;
+ ds.push(d);
+ break;
+ }
+ if (!found) {
+ break;
+ }
+ }
+ return ds;
+}
+exports.getWithdrawDenomList = getWithdrawDenomList;
+/**
+ * Get information about a withdrawal from
+ * a taler://withdraw URI by asking the bank.
+ */
+function getBankWithdrawalInfo(ws, talerWithdrawUri) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const uriResult = taleruri.parseWithdrawUri(talerWithdrawUri);
+ if (!uriResult) {
+ throw Error(`can't parse URL ${talerWithdrawUri}`);
+ }
+ const resp = yield ws.http.get(uriResult.statusUrl);
+ if (resp.status !== 200) {
+ throw Error(`unexpected status (${resp.status}) from bank for ${uriResult.statusUrl}`);
+ }
+ const respJson = yield resp.json();
+ console.log("resp:", respJson);
+ const status = talerTypes.codecForWithdrawOperationStatusResponse().decode(respJson);
+ return {
+ amount: Amounts.parseOrThrow(status.amount),
+ confirmTransferUrl: status.confirm_transfer_url,
+ extractedStatusUrl: uriResult.statusUrl,
+ selectionDone: status.selection_done,
+ senderWire: status.sender_wire,
+ suggestedExchange: status.suggested_exchange,
+ transferDone: status.transfer_done,
+ wireTypes: status.wire_types,
+ };
+ });
+}
+exports.getBankWithdrawalInfo = getBankWithdrawalInfo;
+function getPossibleDenoms(ws, exchangeBaseUrl) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ return yield ws.db
+ .iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, exchangeBaseUrl)
+ .filter((d) => {
+ return ((d.status === dbTypes.DenominationStatus.Unverified ||
+ d.status === dbTypes.DenominationStatus.VerifiedGood) &&
+ !d.isRevoked);
+ });
+ });
+}
+/**
+ * Given a planchet, withdraw a coin from the exchange.
+ */
+function processPlanchet(ws, withdrawalGroupId, coinIdx) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const withdrawalGroup = yield ws.db.get(dbTypes.Stores.withdrawalGroups, withdrawalGroupId);
+ if (!withdrawalGroup) {
+ return;
+ }
+ if (withdrawalGroup.withdrawn[coinIdx]) {
+ return;
+ }
+ const planchet = withdrawalGroup.planchets[coinIdx];
+ if (!planchet) {
+ console.log("processPlanchet: planchet not found");
+ return;
+ }
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, withdrawalGroup.exchangeBaseUrl);
+ if (!exchange) {
+ console.error("db inconsistent: exchange for planchet not found");
+ return;
+ }
+ const denom = yield ws.db.get(dbTypes.Stores.denominations, [
+ withdrawalGroup.exchangeBaseUrl,
+ planchet.denomPub,
+ ]);
+ if (!denom) {
+ console.error("db inconsistent: denom for planchet not found");
+ return;
+ }
+ const wd = {};
+ wd.denom_pub_hash = planchet.denomPubHash;
+ wd.reserve_pub = planchet.reservePub;
+ wd.reserve_sig = planchet.withdrawSig;
+ wd.coin_ev = planchet.coinEv;
+ const reqUrl = new URL(`reserves/${planchet.reservePub}/withdraw`, exchange.baseUrl).href;
+ const resp = yield ws.http.postJson(reqUrl, wd);
+ const r = yield errors.scrutinizeTalerJsonResponse(resp, talerTypes.codecForWithdrawResponse());
+ const denomSig = yield ws.cryptoApi.rsaUnblind(r.ev_sig, planchet.blindingKey, planchet.denomPub);
+ const isValid = yield ws.cryptoApi.rsaVerify(planchet.coinPub, denomSig, planchet.denomPub);
+ if (!isValid) {
+ throw Error("invalid RSA signature by the exchange");
+ }
+ const coin = {
+ blindingKey: planchet.blindingKey,
+ coinPriv: planchet.coinPriv,
+ coinPub: planchet.coinPub,
+ currentAmount: planchet.coinValue,
+ denomPub: planchet.denomPub,
+ denomPubHash: planchet.denomPubHash,
+ denomSig,
+ exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl,
+ status: "fresh" /* Fresh */,
+ coinSource: {
+ type: "withdraw" /* Withdraw */,
+ coinIndex: coinIdx,
+ reservePub: planchet.reservePub,
+ withdrawalGroupId: withdrawalGroupId,
+ },
+ suspended: false,
+ };
+ let withdrawalGroupFinished = false;
+ const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.withdrawalGroups, dbTypes.Stores.reserves], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const ws = yield tx.get(dbTypes.Stores.withdrawalGroups, withdrawalGroupId);
+ if (!ws) {
+ return false;
+ }
+ if (ws.withdrawn[coinIdx]) {
+ // Already withdrawn
+ return false;
+ }
+ ws.withdrawn[coinIdx] = true;
+ delete ws.lastErrorPerCoin[coinIdx];
+ let numDone = 0;
+ for (let i = 0; i < ws.withdrawn.length; i++) {
+ if (ws.withdrawn[i]) {
+ numDone++;
+ }
+ }
+ if (numDone === ws.denoms.length) {
+ ws.timestampFinish = time.getTimestampNow();
+ ws.lastError = undefined;
+ ws.retryInfo = dbTypes.initRetryInfo(false);
+ withdrawalGroupFinished = true;
+ }
+ yield tx.put(dbTypes.Stores.withdrawalGroups, ws);
+ yield tx.add(dbTypes.Stores.coins, coin);
+ return true;
+ }));
+ if (success) {
+ ws.notify({
+ type: "coin-withdrawn" /* CoinWithdrawn */,
+ });
+ }
+ if (withdrawalGroupFinished) {
+ ws.notify({
+ type: "withdraw-group-finished" /* WithdrawGroupFinished */,
+ withdrawalSource: withdrawalGroup.source,
+ });
+ }
+ });
+}
+/**
+ * Get a list of denominations to withdraw from the given exchange for the
+ * given amount, making sure that all denominations' signatures are verified.
+ *
+ * Writes to the DB in order to record the result from verifying
+ * denominations.
+ */
+function getVerifiedWithdrawDenomList(ws, exchangeBaseUrl, amount) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const exchange = yield ws.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
+ if (!exchange) {
+ console.log("exchange not found");
+ throw Error(`exchange ${exchangeBaseUrl} not found`);
+ }
+ const exchangeDetails = exchange.details;
+ if (!exchangeDetails) {
+ console.log("exchange details not available");
+ throw Error(`exchange ${exchangeBaseUrl} details not available`);
+ }
+ console.log("getting possible denoms");
+ const possibleDenoms = yield getPossibleDenoms(ws, exchange.baseUrl);
+ console.log("got possible denoms");
+ let allValid = false;
+ let selectedDenoms;
+ do {
+ allValid = true;
+ selectedDenoms = getWithdrawDenomList(amount, possibleDenoms);
+ console.log("got withdraw denom list");
+ for (const denom of selectedDenoms || []) {
+ if (denom.status === dbTypes.DenominationStatus.Unverified) {
+ console.log("checking validity", denom, exchangeDetails.masterPublicKey);
+ const valid = yield ws.cryptoApi.isValidDenom(denom, exchangeDetails.masterPublicKey);
+ console.log("done checking validity");
+ if (!valid) {
+ denom.status = dbTypes.DenominationStatus.VerifiedBad;
+ allValid = false;
+ }
+ else {
+ denom.status = dbTypes.DenominationStatus.VerifiedGood;
+ }
+ yield ws.db.put(dbTypes.Stores.denominations, denom);
+ }
+ }
+ } while (selectedDenoms.length > 0 && !allValid);
+ console.log("returning denoms");
+ return selectedDenoms;
+ });
+}
+exports.getVerifiedWithdrawDenomList = getVerifiedWithdrawDenomList;
+function incrementWithdrawalRetry(ws, withdrawalGroupId, err) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.withdrawalGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const wsr = yield tx.get(dbTypes.Stores.withdrawalGroups, withdrawalGroupId);
+ if (!wsr) {
+ return;
+ }
+ if (!wsr.retryInfo) {
+ return;
+ }
+ wsr.retryInfo.retryCounter++;
+ dbTypes.updateRetryInfoTimeout(wsr.retryInfo);
+ wsr.lastError = err;
+ yield tx.put(dbTypes.Stores.withdrawalGroups, wsr);
+ }));
+ ws.notify({ type: "withdraw-error" /* WithdrawOperationError */ });
+ });
+}
+function processWithdrawGroup(ws, withdrawalGroupId, forceNow = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const onOpErr = (e) => incrementWithdrawalRetry(ws, withdrawalGroupId, e);
+ yield errors.guardOperationException(() => processWithdrawGroupImpl(ws, withdrawalGroupId, forceNow), onOpErr);
+ });
+}
+exports.processWithdrawGroup = processWithdrawGroup;
+function resetWithdrawalGroupRetry(ws, withdrawalGroupId) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.withdrawalGroups, withdrawalGroupId, (x) => {
+ if (x.retryInfo.active) {
+ x.retryInfo = dbTypes.initRetryInfo();
+ }
+ return x;
+ });
+ });
+}
+function processWithdrawGroupImpl(ws, withdrawalGroupId, forceNow) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ logger.trace("processing withdraw group", withdrawalGroupId);
+ if (forceNow) {
+ yield resetWithdrawalGroupRetry(ws, withdrawalGroupId);
+ }
+ const withdrawalGroup = yield ws.db.get(dbTypes.Stores.withdrawalGroups, withdrawalGroupId);
+ if (!withdrawalGroup) {
+ logger.trace("withdraw session doesn't exist");
+ return;
+ }
+ const ps = withdrawalGroup.denoms.map((d, i) => processPlanchet(ws, withdrawalGroupId, i));
+ yield Promise.all(ps);
+ return;
+ });
+}
+function getExchangeWithdrawalInfo(ws, baseUrl, amount) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const exchangeInfo = yield exchanges.updateExchangeFromUrl(ws, baseUrl);
+ const exchangeDetails = exchangeInfo.details;
+ if (!exchangeDetails) {
+ throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
+ }
+ const exchangeWireInfo = exchangeInfo.wireInfo;
+ if (!exchangeWireInfo) {
+ throw Error(`exchange ${exchangeInfo.baseUrl} wire details not available`);
+ }
+ const selectedDenoms = yield getVerifiedWithdrawDenomList(ws, baseUrl, amount);
+ let acc = Amounts.getZero(amount.currency);
+ for (const d of selectedDenoms) {
+ acc = Amounts.add(acc, d.feeWithdraw).amount;
+ }
+ const actualCoinCost = selectedDenoms
+ .map((d) => Amounts.add(d.value, d.feeWithdraw).amount)
+ .reduce((a, b) => Amounts.add(a, b).amount);
+ const exchangeWireAccounts = [];
+ for (const account of exchangeWireInfo.accounts) {
+ exchangeWireAccounts.push(account.payto_uri);
+ }
+ const { isTrusted, isAudited } = yield exchanges.getExchangeTrust(ws, exchangeInfo);
+ let earliestDepositExpiration = selectedDenoms[0].stampExpireDeposit;
+ for (let i = 1; i < selectedDenoms.length; i++) {
+ const expireDeposit = selectedDenoms[i].stampExpireDeposit;
+ if (expireDeposit.t_ms < earliestDepositExpiration.t_ms) {
+ earliestDepositExpiration = expireDeposit;
+ }
+ }
+ const possibleDenoms = yield ws.db
+ .iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, baseUrl)
+ .filter((d) => d.isOffered);
+ const trustedAuditorPubs = [];
+ const currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, amount.currency);
+ if (currencyRecord) {
+ trustedAuditorPubs.push(...currencyRecord.auditors.map((a) => a.auditorPub));
+ }
+ let versionMatch;
+ if (exchangeDetails.protocolVersion) {
+ versionMatch = LibtoolVersion.compare(versions.WALLET_EXCHANGE_PROTOCOL_VERSION, exchangeDetails.protocolVersion);
+ if (versionMatch &&
+ !versionMatch.compatible &&
+ versionMatch.currentCmp === -1) {
+ console.warn(`wallet's support for exchange protocol version ${versions.WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
+ `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`);
+ }
+ }
+ let tosAccepted = false;
+ if (exchangeInfo.termsOfServiceAcceptedTimestamp) {
+ if (exchangeInfo.termsOfServiceAcceptedEtag ==
+ exchangeInfo.termsOfServiceLastEtag) {
+ tosAccepted = true;
+ }
+ }
+ const ret = {
+ earliestDepositExpiration,
+ exchangeInfo,
+ exchangeWireAccounts,
+ exchangeVersion: exchangeDetails.protocolVersion || "unknown",
+ isAudited,
+ isTrusted,
+ numOfferedDenoms: possibleDenoms.length,
+ overhead: Amounts.sub(amount, actualCoinCost).amount,
+ selectedDenoms,
+ trustedAuditorPubs,
+ versionMatch,
+ walletVersion: versions.WALLET_EXCHANGE_PROTOCOL_VERSION,
+ wireFees: exchangeWireInfo,
+ withdrawFee: acc,
+ termsOfServiceAccepted: tosAccepted,
+ };
+ return ret;
+ });
+}
+exports.getExchangeWithdrawalInfo = getExchangeWithdrawalInfo;
+function getWithdrawDetailsForUri(ws, talerWithdrawUri, maybeSelectedExchange) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const info = yield getBankWithdrawalInfo(ws, talerWithdrawUri);
+ let rci = undefined;
+ if (maybeSelectedExchange) {
+ rci = yield getExchangeWithdrawalInfo(ws, maybeSelectedExchange, info.amount);
+ }
+ return {
+ bankWithdrawDetails: info,
+ exchangeWithdrawDetails: rci,
+ };
+ });
+}
+exports.getWithdrawDetailsForUri = getWithdrawDetailsForUri;
+
+});
+
+unwrapExports(withdraw);
+var withdraw_1 = withdraw.getWithdrawDenomList;
+var withdraw_2 = withdraw.getBankWithdrawalInfo;
+var withdraw_3 = withdraw.getVerifiedWithdrawDenomList;
+var withdraw_4 = withdraw.processWithdrawGroup;
+var withdraw_5 = withdraw.getExchangeWithdrawalInfo;
+var withdraw_6 = withdraw.getWithdrawDetailsForUri;
+
var http = createCommonjsModule(function (module, exports) {
/*
This file is part of TALER
@@ -8860,16 +9640,8 @@ var http = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
var HttpResponseStatus;
(function (HttpResponseStatus) {
HttpResponseStatus[HttpResponseStatus["Ok"] = 200] = "Ok";
@@ -8908,10 +9680,9 @@ exports.Headers = Headers;
class BrowserHttpLib {
req(method, url, requestBody, options) {
return new Promise((resolve, reject) => {
- var _a;
const myRequest = new XMLHttpRequest();
myRequest.open(method, url);
- if ((_a = options) === null || _a === void 0 ? void 0 : _a.headers) {
+ if (options === null || options === void 0 ? void 0 : options.headers) {
for (const headerName in options.headers) {
myRequest.setRequestHeader(headerName, options.headers[headerName]);
}
@@ -8922,17 +9693,17 @@ class BrowserHttpLib {
else {
myRequest.send();
}
- myRequest.onerror = e => {
+ myRequest.onerror = (e) => {
console.error("http request error");
reject(Error("could not make XMLHttpRequest"));
};
- myRequest.addEventListener("readystatechange", e => {
+ myRequest.addEventListener("readystatechange", (e) => {
if (myRequest.readyState === XMLHttpRequest.DONE) {
if (myRequest.status === 0) {
reject(Error("HTTP Request failed (status code 0, maybe URI scheme is wrong?)"));
return;
}
- const makeJson = () => __awaiter(this, void 0, void 0, function* () {
+ const makeJson = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let responseJson;
try {
responseJson = JSON.parse(myRequest.responseText);
@@ -8951,15 +9722,19 @@ class BrowserHttpLib {
const headerMap = new Headers();
arr.forEach(function (line) {
const parts = line.split(": ");
- const header = parts.shift();
+ const headerName = parts.shift();
+ if (!headerName) {
+ console.error("invalid header");
+ return;
+ }
const value = parts.join(": ");
- headerMap.set(header, value);
+ headerMap.set(headerName, value);
});
const resp = {
status: myRequest.status,
headers: headerMap,
json: makeJson,
- text: () => __awaiter(this, void 0, void 0, function* () { return myRequest.responseText; }),
+ text: () => tslib_1.__awaiter(this, void 0, void 0, function* () { return myRequest.responseText; }),
};
resolve(resp);
}
@@ -9001,27 +9776,12 @@ var refund = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+
@@ -9031,9 +9791,9 @@ const Amounts = __importStar(amounts);
const logger = new logging.Logger("refund.ts");
function incrementPurchaseQueryRefundRetry(ws, proposalId, err) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
console.log("incrementing purchase refund query retry with error", err);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const pr = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!pr) {
return;
@@ -9050,9 +9810,9 @@ function incrementPurchaseQueryRefundRetry(ws, proposalId, err) {
});
}
function incrementPurchaseApplyRefundRetry(ws, proposalId, err) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
console.log("incrementing purchase refund apply retry with error", err);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const pr = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!pr) {
return;
@@ -9069,7 +9829,7 @@ function incrementPurchaseApplyRefundRetry(ws, proposalId, err) {
});
}
function getFullRefundFees(ws, refundPermissions) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (refundPermissions.length === 0) {
throw Error("no refunds given");
}
@@ -9077,7 +9837,7 @@ function getFullRefundFees(ws, refundPermissions) {
if (!coin0) {
throw Error("coin not found");
}
- let feeAcc = Amounts.getZero(Amounts.parseOrThrow(refundPermissions[0].refund_amount).currency);
+ let feeAcc = amounts.Amounts.getZero(amounts.Amounts.parseOrThrow(refundPermissions[0].refund_amount).currency);
const denoms = yield ws.db
.iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, coin0.exchangeBaseUrl)
.toArray();
@@ -9097,21 +9857,21 @@ function getFullRefundFees(ws, refundPermissions) {
// When it hasn't, the refresh cost is inaccurate. To fix this,
// we need introduce a flag to tell if a coin was refunded or
// refreshed normally (and what about incremental refunds?)
- const refundAmount = Amounts.parseOrThrow(rp.refund_amount);
- const refundFee = Amounts.parseOrThrow(rp.refund_fee);
- const refreshCost = refresh.getTotalRefreshCost(denoms, denom, Amounts.sub(refundAmount, refundFee).amount);
- feeAcc = Amounts.add(feeAcc, refreshCost, refundFee).amount;
+ const refundAmount = amounts.Amounts.parseOrThrow(rp.refund_amount);
+ const refundFee = amounts.Amounts.parseOrThrow(rp.refund_fee);
+ const refreshCost = refresh.getTotalRefreshCost(denoms, denom, amounts.Amounts.sub(refundAmount, refundFee).amount);
+ feeAcc = amounts.Amounts.add(feeAcc, refreshCost, refundFee).amount;
}
return feeAcc;
});
}
exports.getFullRefundFees = getFullRefundFees;
function acceptRefundResponse(ws, proposalId, refundResponse, reason) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const refundPermissions = refundResponse.refund_permissions;
let numNewRefunds = 0;
const refundGroupId = talerCrypto.encodeCrock(naclFast.randomBytes(32));
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!p) {
console.error("purchase not found, not adding refunds");
@@ -9176,8 +9936,8 @@ function acceptRefundResponse(ws, proposalId, refundResponse, reason) {
}
exports.acceptRefundResponse = acceptRefundResponse;
function startRefundQuery(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!p) {
console.log("no purchase found for refund URL");
@@ -9203,7 +9963,7 @@ function startRefundQuery(ws, proposalId) {
* that was involved in the refund.
*/
function applyRefund(ws, talerRefundUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const parseResult = taleruri.parseRefundUri(talerRefundUri);
console.log("applying refund", parseResult);
if (!parseResult) {
@@ -9216,22 +9976,22 @@ function applyRefund(ws, talerRefundUri) {
if (!purchase) {
throw Error(`no purchase for the taler://refund/ URI (${talerRefundUri}) was found`);
}
- console.log("processing purchase for refund");
+ logger.info("processing purchase for refund");
yield startRefundQuery(ws, purchase.proposalId);
- return purchase.contractData.contractTermsHash;
+ return { contractTermsHash: purchase.contractData.contractTermsHash };
});
}
exports.applyRefund = applyRefund;
function processPurchaseQueryRefund(ws, proposalId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (e) => incrementPurchaseQueryRefundRetry(ws, proposalId, e);
yield errors.guardOperationException(() => processPurchaseQueryRefundImpl(ws, proposalId, forceNow), onOpErr);
});
}
exports.processPurchaseQueryRefund = processPurchaseQueryRefund;
function resetPurchaseQueryRefundRetry(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, (x) => {
if (x.refundStatusRetryInfo.active) {
x.refundStatusRetryInfo = dbTypes.initRetryInfo();
}
@@ -9240,7 +10000,7 @@ function resetPurchaseQueryRefundRetry(ws, proposalId) {
});
}
function processPurchaseQueryRefundImpl(ws, proposalId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetPurchaseQueryRefundRetry(ws, proposalId);
}
@@ -9270,15 +10030,15 @@ function processPurchaseQueryRefundImpl(ws, proposalId, forceNow) {
});
}
function processPurchaseApplyRefund(ws, proposalId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (e) => incrementPurchaseApplyRefundRetry(ws, proposalId, e);
yield errors.guardOperationException(() => processPurchaseApplyRefundImpl(ws, proposalId, forceNow), onOpErr);
});
}
exports.processPurchaseApplyRefund = processPurchaseApplyRefund;
function resetPurchaseApplyRefundRetry(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, (x) => {
if (x.refundApplyRetryInfo.active) {
x.refundApplyRetryInfo = dbTypes.initRetryInfo();
}
@@ -9287,7 +10047,7 @@ function resetPurchaseApplyRefundRetry(ws, proposalId) {
});
}
function processPurchaseApplyRefundImpl(ws, proposalId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetPurchaseApplyRefundRetry(ws, proposalId);
}
@@ -9318,7 +10078,7 @@ function processPurchaseApplyRefundImpl(ws, proposalId, forceNow) {
console.log("sending refund permission", perm);
// FIXME: not correct once we support multiple exchanges per payment
const exchangeUrl = purchase.payReq.coins[0].exchange_url;
- const reqUrl = new URL("refund", exchangeUrl);
+ const reqUrl = new URL(`coins/${perm.coin_pub}/refund`, exchangeUrl);
const resp = yield ws.http.postJson(reqUrl.href, req);
console.log("sent refund permission");
switch (resp.status) {
@@ -9329,33 +10089,32 @@ function processPurchaseApplyRefundImpl(ws, proposalId, forceNow) {
// We're too late, refund is expired.
newRefundsFailed[pk] = info;
break;
- default:
+ default: {
let body = null;
- try {
- body = yield resp.json();
- }
- catch (_a) { }
+ // FIXME: error handling!
+ body = yield resp.json();
const m = "refund request (at exchange) failed";
- throw new errors.OperationFailedError(m, {
+ throw new errors.OperationFailedError({
message: m,
type: "network",
details: {
body,
},
});
+ }
}
}
let allRefundsProcessed = false;
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases, dbTypes.Stores.coins, dbTypes.Stores.refreshGroups, dbTypes.Stores.refundEvents], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases, dbTypes.Stores.coins, dbTypes.Stores.refreshGroups, dbTypes.Stores.refundEvents], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!p) {
return;
}
// Groups that failed/succeeded
- let groups = {};
+ const groups = {};
// Avoid duplicates
const refreshCoinsMap = {};
- const modCoin = (perm) => __awaiter(this, void 0, void 0, function* () {
+ const modCoin = (perm) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const c = yield tx.get(dbTypes.Stores.coins, perm.coin_pub);
if (!c) {
console.warn("coin not found, can't apply refund");
@@ -9363,15 +10122,15 @@ function processPurchaseApplyRefundImpl(ws, proposalId, forceNow) {
}
refreshCoinsMap[c.coinPub] = { coinPub: c.coinPub };
logger.trace(`commiting refund ${perm.merchant_sig} to coin ${c.coinPub}`);
- logger.trace(`coin amount before is ${Amounts.toString(c.currentAmount)}`);
+ logger.trace(`coin amount before is ${amounts.Amounts.stringify(c.currentAmount)}`);
logger.trace(`refund amount (via merchant) is ${perm.refund_amount}`);
logger.trace(`refund fee (via merchant) is ${perm.refund_fee}`);
- const refundAmount = Amounts.parseOrThrow(perm.refund_amount);
- const refundFee = Amounts.parseOrThrow(perm.refund_fee);
- c.status = dbTypes.CoinStatus.Dormant;
- c.currentAmount = Amounts.add(c.currentAmount, refundAmount).amount;
- c.currentAmount = Amounts.sub(c.currentAmount, refundFee).amount;
- logger.trace(`coin amount after is ${Amounts.toString(c.currentAmount)}`);
+ const refundAmount = amounts.Amounts.parseOrThrow(perm.refund_amount);
+ const refundFee = amounts.Amounts.parseOrThrow(perm.refund_fee);
+ c.status = "dormant" /* Dormant */;
+ c.currentAmount = amounts.Amounts.add(c.currentAmount, refundAmount).amount;
+ c.currentAmount = amounts.Amounts.sub(c.currentAmount, refundFee).amount;
+ logger.trace(`coin amount after is ${amounts.Amounts.stringify(c.currentAmount)}`);
yield tx.put(dbTypes.Stores.coins, c);
});
for (const pk of Object.keys(newRefundsFailed)) {
@@ -9461,23 +10220,8 @@ var pay = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Implementation of the payment operation, including downloading and
* claiming of proposals.
@@ -9490,7 +10234,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+const Amounts = tslib_1.__importStar(amounts);
@@ -9510,7 +10254,7 @@ const logger = new logging.Logger("pay.ts");
* of coins that are too small to spend.
*/
function getTotalPaymentCost(ws, pcs) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const costs = [
pcs.paymentAmount,
pcs.customerDepositFees,
@@ -9562,8 +10306,8 @@ function selectPayCoins(acis, paymentAmount, depositFeeLimit) {
let totalFees = Amounts.getZero(currency);
let amountPayRemaining = paymentAmount;
let amountDepositFeeLimitRemaining = depositFeeLimit;
- let customerWireFees = Amounts.getZero(currency);
- let customerDepositFees = Amounts.getZero(currency);
+ const customerWireFees = Amounts.getZero(currency);
+ const customerDepositFees = Amounts.getZero(currency);
for (const aci of acis) {
// Don't use this coin if depositing it is more expensive than
// the amount it would give the merchant.
@@ -9586,12 +10330,18 @@ function selectPayCoins(acis, paymentAmount, depositFeeLimit) {
let coinSpend;
const amountActualAvailable = Amounts.sub(aci.availableAmount, depositFeeSpend).amount;
if (Amounts.cmp(amountActualAvailable, amountPayRemaining) > 0) {
- // Partial spending
+ // Partial spending, as the coin is worth more than the remaining
+ // amount to pay.
coinSpend = Amounts.add(amountPayRemaining, depositFeeSpend).amount;
+ // Make sure we contribute at least the deposit fee, otherwise
+ // contributing this coin would cause a loss for the merchant.
+ if (Amounts.cmp(coinSpend, aci.feeDeposit) < 0) {
+ coinSpend = aci.feeDeposit;
+ }
amountPayRemaining = Amounts.getZero(currency);
}
else {
- // Spend the full remaining amount
+ // Spend the full remaining amount on the coin
coinSpend = aci.availableAmount;
amountPayRemaining = Amounts.add(amountPayRemaining, depositFeeSpend)
.amount;
@@ -9621,7 +10371,7 @@ exports.selectPayCoins = selectPayCoins;
* If payment is impossible, undefined is returned.
*/
function getCoinsForPayment(ws, contractData) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
let remainingAmount = contractData.amount;
const exchanges = yield ws.db.iter(dbTypes.Stores.exchanges).toArray();
for (const exchange of exchanges) {
@@ -9661,9 +10411,6 @@ function getCoinsForPayment(ws, contractData) {
const coins = yield ws.db
.iterIndex(dbTypes.Stores.coins.exchangeBaseUrlIndex, exchange.baseUrl)
.toArray();
- const denoms = yield ws.db
- .iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, exchange.baseUrl)
- .toArray();
if (!coins || coins.length === 0) {
continue;
}
@@ -9693,7 +10440,7 @@ function getCoinsForPayment(ws, contractData) {
if (coin.suspended) {
continue;
}
- if (coin.status !== dbTypes.CoinStatus.Fresh) {
+ if (coin.status !== "fresh" /* Fresh */) {
continue;
}
acis.push({
@@ -9733,7 +10480,7 @@ function getCoinsForPayment(ws, contractData) {
* pay for a proposal in the wallet's database.
*/
function recordConfirmPay(ws, proposal, coinSelection, coinDepositPermissions, sessionIdOverride) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const d = proposal.download;
if (!d) {
throw Error("proposal is in invalid state");
@@ -9779,7 +10526,7 @@ function recordConfirmPay(ws, proposal, coinSelection, coinDepositPermissions, s
refundsPending: {},
},
};
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.purchases, dbTypes.Stores.proposals, dbTypes.Stores.refreshGroups], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.purchases, dbTypes.Stores.proposals, dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.proposals, proposal.proposalId);
if (p) {
p.proposalStatus = "accepted" /* ACCEPTED */;
@@ -9793,7 +10540,7 @@ function recordConfirmPay(ws, proposal, coinSelection, coinDepositPermissions, s
if (!coin) {
throw Error("coin allocated for payment doesn't exist anymore");
}
- coin.status = dbTypes.CoinStatus.Dormant;
+ coin.status = "dormant" /* Dormant */;
const remaining = Amounts.sub(coin.currentAmount, coinSelection.coinContributions[i]);
if (remaining.saturated) {
throw Error("not enough remaining balance on coin for payment");
@@ -9801,7 +10548,9 @@ function recordConfirmPay(ws, proposal, coinSelection, coinDepositPermissions, s
coin.currentAmount = remaining.amount;
yield tx.put(dbTypes.Stores.coins, coin);
}
- const refreshCoinPubs = coinSelection.coinPubs.map(x => ({ coinPub: x }));
+ const refreshCoinPubs = coinSelection.coinPubs.map((x) => ({
+ coinPub: x,
+ }));
yield refresh.createRefreshGroup(tx, refreshCoinPubs, "pay" /* Pay */);
}));
ws.notify({
@@ -9823,7 +10572,7 @@ function getNextUrl(contractData) {
}
}
function abortFailedPayment(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const purchase = yield ws.db.get(dbTypes.Stores.purchases, proposalId);
if (!purchase) {
throw Error("Purchase not found, unable to abort with refund");
@@ -9856,7 +10605,7 @@ function abortFailedPayment(ws, proposalId) {
}
const refundResponse = talerTypes.codecForMerchantRefundResponse().decode(yield resp.json());
yield refund.acceptRefundResponse(ws, purchase.proposalId, refundResponse, "abort-refund" /* AbortRefund */);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!p) {
return;
@@ -9868,8 +10617,8 @@ function abortFailedPayment(ws, proposalId) {
}
exports.abortFailedPayment = abortFailedPayment;
function incrementProposalRetry(ws, proposalId, err) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const pr = yield tx.get(dbTypes.Stores.proposals, proposalId);
if (!pr) {
return;
@@ -9886,9 +10635,9 @@ function incrementProposalRetry(ws, proposalId, err) {
});
}
function incrementPurchasePayRetry(ws, proposalId, err) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
console.log("incrementing purchase pay retry with error", err);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const pr = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!pr) {
return;
@@ -9905,15 +10654,15 @@ function incrementPurchasePayRetry(ws, proposalId, err) {
});
}
function processDownloadProposal(ws, proposalId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (err) => incrementProposalRetry(ws, proposalId, err);
yield errors.guardOperationException(() => processDownloadProposalImpl(ws, proposalId, forceNow), onOpErr);
});
}
exports.processDownloadProposal = processDownloadProposal;
function resetDownloadProposalRetry(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.proposals, proposalId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.proposals, proposalId, (x) => {
if (x.retryInfo.active) {
x.retryInfo = dbTypes.initRetryInfo();
}
@@ -9922,7 +10671,7 @@ function resetDownloadProposalRetry(ws, proposalId) {
});
}
function processDownloadProposalImpl(ws, proposalId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetDownloadProposalRetry(ws, proposalId);
}
@@ -9952,7 +10701,7 @@ function processDownloadProposalImpl(ws, proposalId, forceNow) {
const contractTermsHash = yield ws.cryptoApi.hashString(helpers.canonicalJson(proposalResp.contract_terms));
const parsedContractTerms = talerTypes.codecForContractTerms().decode(proposalResp.contract_terms);
const fulfillmentUrl = parsedContractTerms.fulfillment_url;
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals, dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals, dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.proposals, proposalId);
if (!p) {
return;
@@ -9983,11 +10732,11 @@ function processDownloadProposalImpl(ws, proposalId, forceNow) {
payDeadline: parsedContractTerms.pay_deadline,
refundDeadline: parsedContractTerms.refund_deadline,
wireFeeAmortization: parsedContractTerms.wire_fee_amortization || 1,
- allowedAuditors: parsedContractTerms.auditors.map(x => ({
+ allowedAuditors: parsedContractTerms.auditors.map((x) => ({
auditorBaseUrl: x.url,
auditorPub: x.master_pub,
})),
- allowedExchanges: parsedContractTerms.exchanges.map(x => ({
+ allowedExchanges: parsedContractTerms.exchanges.map((x) => ({
exchangeBaseUrl: x.url,
exchangePub: x.master_pub,
})),
@@ -10026,7 +10775,7 @@ function processDownloadProposalImpl(ws, proposalId, forceNow) {
* downloaded in the context of a session ID.
*/
function startDownloadProposal(ws, merchantBaseUrl, orderId, sessionId) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const oldProposal = yield ws.db.getIndexed(dbTypes.Stores.proposals.urlAndOrderIdIndex, [merchantBaseUrl, orderId]);
if (oldProposal) {
yield processDownloadProposal(ws, oldProposal.proposalId);
@@ -10048,7 +10797,7 @@ function startDownloadProposal(ws, merchantBaseUrl, orderId, sessionId) {
lastError: undefined,
downloadSessionId: sessionId,
};
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const existingRecord = yield tx.getIndexed(dbTypes.Stores.proposals.urlAndOrderIdIndex, [merchantBaseUrl, orderId]);
if (existingRecord) {
// Created concurrently
@@ -10061,7 +10810,7 @@ function startDownloadProposal(ws, merchantBaseUrl, orderId, sessionId) {
});
}
function submitPay(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const purchase = yield ws.db.get(dbTypes.Stores.purchases, proposalId);
if (!purchase) {
throw Error("Purchase not found: " + proposalId);
@@ -10112,7 +10861,7 @@ function submitPay(ws, proposalId) {
purchase.autoRefundDeadline = time.timestampAddDuration(now, ar);
}
}
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases, dbTypes.Stores.payEvents], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases, dbTypes.Stores.payEvents], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
yield tx.put(dbTypes.Stores.purchases, purchase);
const payEvent = {
proposalId,
@@ -10138,7 +10887,7 @@ exports.submitPay = submitPay;
* yet send to the merchant.
*/
function preparePayForUri(ws, talerPayUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const uriResult = taleruri.parsePayUri(talerPayUri);
if (!uriResult) {
return {
@@ -10197,7 +10946,7 @@ function preparePayForUri(ws, talerPayUri) {
}
if (uriResult.sessionId && purchase.lastSessionId !== uriResult.sessionId) {
console.log("automatically re-submitting payment with different session ID");
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.purchases], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = yield tx.get(dbTypes.Stores.purchases, proposalId);
if (!p) {
return;
@@ -10219,7 +10968,7 @@ exports.preparePayForUri = preparePayForUri;
* Add a contract to the wallet and sign coins, and send them.
*/
function confirmPay(ws, proposalId, sessionIdOverride) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
logger.trace(`executing confirmPay with proposalId ${proposalId} and sessionIdOverride ${sessionIdOverride}`);
const proposal = yield ws.db.get(dbTypes.Stores.proposals, proposalId);
if (!proposal) {
@@ -10234,7 +10983,7 @@ function confirmPay(ws, proposalId, sessionIdOverride) {
if (sessionIdOverride !== undefined &&
sessionIdOverride != purchase.lastSessionId) {
logger.trace(`changing session ID to ${sessionIdOverride}`);
- yield ws.db.mutate(dbTypes.Stores.purchases, purchase.proposalId, x => {
+ yield ws.db.mutate(dbTypes.Stores.purchases, purchase.proposalId, (x) => {
x.lastSessionId = sessionIdOverride;
x.paymentSubmitPending = true;
return x;
@@ -10288,15 +11037,15 @@ function confirmPay(ws, proposalId, sessionIdOverride) {
}
exports.confirmPay = confirmPay;
function processPurchasePay(ws, proposalId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (e) => incrementPurchasePayRetry(ws, proposalId, e);
yield errors.guardOperationException(() => processPurchasePayImpl(ws, proposalId, forceNow), onOpErr);
});
}
exports.processPurchasePay = processPurchasePay;
function resetPurchasePayRetry(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.purchases, proposalId, (x) => {
if (x.payRetryInfo.active) {
x.payRetryInfo = dbTypes.initRetryInfo();
}
@@ -10305,7 +11054,7 @@ function resetPurchasePayRetry(ws, proposalId) {
});
}
function processPurchasePayImpl(ws, proposalId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetPurchasePayRetry(ws, proposalId);
}
@@ -10321,8 +11070,8 @@ function processPurchasePayImpl(ws, proposalId, forceNow) {
});
}
function refuseProposal(ws, proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
- const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.proposals], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const proposal = yield tx.get(dbTypes.Stores.proposals, proposalId);
if (!proposal) {
logger.trace(`proposal ${proposalId} not found, won't refuse proposal`);
@@ -10357,149 +11106,10 @@ var pay_7 = pay.confirmPay;
var pay_8 = pay.processPurchasePay;
var pay_9 = pay.refuseProposal;
-var assertUnreachable_1 = createCommonjsModule(function (module, exports) {
-/*
- 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/>
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-function assertUnreachable(x) {
- throw new Error("Didn't expect to get here");
-}
-exports.assertUnreachable = assertUnreachable;
-
-});
-
-unwrapExports(assertUnreachable_1);
-var assertUnreachable_2 = assertUnreachable_1.assertUnreachable;
-
-var ReserveTransaction = createCommonjsModule(function (module, exports) {
-/*
- 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/>
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-/**
- * @author Florian Dold <dold@taler.net>
- */
-/**
- * Imports.
- */
-
-
-exports.codecForReserveWithdrawTransaction = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("amount", codec.codecForString)
- .property("h_coin_envelope", codec.codecForString)
- .property("h_denom_pub", codec.codecForString)
- .property("reserve_sig", codec.codecForString)
- .property("type", codec.makeCodecForConstString("WITHDRAW" /* Withdraw */))
- .property("withdraw_fee", codec.codecForString)
- .build("ReserveWithdrawTransaction"));
-exports.codecForReserveDepositTransaction = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("amount", codec.codecForString)
- .property("sender_account_url", codec.codecForString)
- .property("timestamp", time.codecForTimestamp)
- .property("wire_reference", codec.codecForString)
- .property("type", codec.makeCodecForConstString("DEPOSIT" /* Deposit */))
- .build("ReserveDepositTransaction"));
-exports.codecForReserveClosingTransaction = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("amount", codec.codecForString)
- .property("closing_fee", codec.codecForString)
- .property("exchange_pub", codec.codecForString)
- .property("exchange_sig", codec.codecForString)
- .property("h_wire", codec.codecForString)
- .property("timestamp", time.codecForTimestamp)
- .property("type", codec.makeCodecForConstString("CLOSING" /* Closing */))
- .property("wtid", codec.codecForString)
- .build("ReserveClosingTransaction"));
-exports.codecForReservePaybackTransaction = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("amount", codec.codecForString)
- .property("coin_pub", codec.codecForString)
- .property("exchange_pub", codec.codecForString)
- .property("exchange_sig", codec.codecForString)
- .property("receiver_account_details", codec.codecForString)
- .property("timestamp", time.codecForTimestamp)
- .property("type", codec.makeCodecForConstString("PAYBACK" /* Payback */))
- .property("wire_transfer", codec.codecForString)
- .build("ReservePaybackTransaction"));
-exports.codecForReserveTransaction = () => codec.typecheckedCodec(codec.makeCodecForUnion()
- .discriminateOn("type")
- .alternative("WITHDRAW" /* Withdraw */, exports.codecForReserveWithdrawTransaction())
- .alternative("CLOSING" /* Closing */, exports.codecForReserveClosingTransaction())
- .alternative("PAYBACK" /* Payback */, exports.codecForReservePaybackTransaction())
- .alternative("DEPOSIT" /* Deposit */, exports.codecForReserveDepositTransaction())
- .build("ReserveTransaction"));
-
-});
-
-unwrapExports(ReserveTransaction);
-var ReserveTransaction_1 = ReserveTransaction.codecForReserveWithdrawTransaction;
-var ReserveTransaction_2 = ReserveTransaction.codecForReserveDepositTransaction;
-var ReserveTransaction_3 = ReserveTransaction.codecForReserveClosingTransaction;
-var ReserveTransaction_4 = ReserveTransaction.codecForReservePaybackTransaction;
-var ReserveTransaction_5 = ReserveTransaction.codecForReserveTransaction;
-
-var ReserveStatus = createCommonjsModule(function (module, exports) {
-/*
- 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/>
- */
-Object.defineProperty(exports, "__esModule", { value: true });
-/**
- * @author Florian Dold <dold@taler.net>
- */
-/**
- * Imports.
- */
-
-
-exports.codecForReserveStatus = () => codec.typecheckedCodec(codec.makeCodecForObject()
- .property("balance", codec.codecForString)
- .property("history", codec.makeCodecForList(ReserveTransaction.codecForReserveTransaction()))
- .build("ReserveStatus"));
-
-});
-
-unwrapExports(ReserveStatus);
-var ReserveStatus_1 = ReserveStatus.codecForReserveStatus;
-
-var reserves = createCommonjsModule(function (module, exports) {
+var timer = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
- (C) 2019 GNUnet e.V.
+ (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
@@ -10512,607 +11122,6 @@ var reserves = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-
-
-
-
-const Amounts = __importStar(amounts);
-
-
-
-
-
-
-
-
-
-const logger = new logging.Logger("reserves.ts");
-function resetReserveRetry(ws, reservePub) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, x => {
- if (x.retryInfo.active) {
- x.retryInfo = dbTypes.initRetryInfo();
- }
- return x;
- });
- });
-}
-/**
- * Create a reserve, but do not flag it as confirmed yet.
- *
- * Adds the corresponding exchange as a trusted exchange if it is neither
- * audited nor trusted already.
- */
-function createReserve(ws, req) {
- return __awaiter(this, void 0, void 0, function* () {
- const keypair = yield ws.cryptoApi.createEddsaKeypair();
- const now = time.getTimestampNow();
- const canonExchange = helpers.canonicalizeBaseUrl(req.exchange);
- let reserveStatus;
- if (req.bankWithdrawStatusUrl) {
- reserveStatus = dbTypes.ReserveRecordStatus.REGISTERING_BANK;
- }
- else {
- reserveStatus = dbTypes.ReserveRecordStatus.UNCONFIRMED;
- }
- const currency = req.amount.currency;
- const reserveRecord = {
- timestampCreated: now,
- amountWithdrawAllocated: Amounts.getZero(currency),
- amountWithdrawCompleted: Amounts.getZero(currency),
- amountWithdrawRemaining: Amounts.getZero(currency),
- exchangeBaseUrl: canonExchange,
- hasPayback: false,
- amountInitiallyRequested: req.amount,
- reservePriv: keypair.priv,
- reservePub: keypair.pub,
- senderWire: req.senderWire,
- timestampConfirmed: undefined,
- timestampReserveInfoPosted: undefined,
- bankWithdrawStatusUrl: req.bankWithdrawStatusUrl,
- exchangeWire: req.exchangeWire,
- reserveStatus,
- lastSuccessfulStatusQuery: undefined,
- retryInfo: dbTypes.initRetryInfo(),
- lastError: undefined,
- reserveTransactions: [],
- };
- const senderWire = req.senderWire;
- if (senderWire) {
- const rec = {
- paytoUri: senderWire,
- };
- yield ws.db.put(dbTypes.Stores.senderWires, rec);
- }
- const exchangeInfo = yield exchanges.updateExchangeFromUrl(ws, req.exchange);
- const exchangeDetails = exchangeInfo.details;
- if (!exchangeDetails) {
- console.log(exchangeDetails);
- throw Error("exchange not updated");
- }
- const { isAudited, isTrusted } = yield exchanges.getExchangeTrust(ws, exchangeInfo);
- let currencyRecord = yield ws.db.get(dbTypes.Stores.currencies, exchangeDetails.currency);
- if (!currencyRecord) {
- currencyRecord = {
- auditors: [],
- exchanges: [],
- fractionalDigits: 2,
- name: exchangeDetails.currency,
- };
- }
- if (!isAudited && !isTrusted) {
- currencyRecord.exchanges.push({
- baseUrl: req.exchange,
- exchangePub: exchangeDetails.masterPublicKey,
- });
- }
- const cr = currencyRecord;
- const resp = yield ws.db.runWithWriteTransaction([dbTypes.Stores.currencies, dbTypes.Stores.reserves, dbTypes.Stores.bankWithdrawUris], (tx) => __awaiter(this, void 0, void 0, function* () {
- // Check if we have already created a reserve for that bankWithdrawStatusUrl
- if (reserveRecord.bankWithdrawStatusUrl) {
- const bwi = yield tx.get(dbTypes.Stores.bankWithdrawUris, reserveRecord.bankWithdrawStatusUrl);
- if (bwi) {
- const otherReserve = yield tx.get(dbTypes.Stores.reserves, bwi.reservePub);
- if (otherReserve) {
- logger.trace("returning existing reserve for bankWithdrawStatusUri");
- return {
- exchange: otherReserve.exchangeBaseUrl,
- reservePub: otherReserve.reservePub,
- };
- }
- }
- yield tx.put(dbTypes.Stores.bankWithdrawUris, {
- reservePub: reserveRecord.reservePub,
- talerWithdrawUri: reserveRecord.bankWithdrawStatusUrl,
- });
- }
- yield tx.put(dbTypes.Stores.currencies, cr);
- yield tx.put(dbTypes.Stores.reserves, reserveRecord);
- const r = {
- exchange: canonExchange,
- reservePub: keypair.pub,
- };
- return r;
- }));
- ws.notify({ type: "reserve-created" /* ReserveCreated */ });
- // Asynchronously process the reserve, but return
- // to the caller already.
- processReserve(ws, resp.reservePub, true).catch(e => {
- console.error("Processing reserve failed:", e);
- });
- return resp;
- });
-}
-exports.createReserve = createReserve;
-/**
- * First fetch information requred to withdraw from the reserve,
- * then deplete the reserve, withdrawing coins until it is empty.
- *
- * The returned promise resolves once the reserve is set to the
- * state DORMANT.
- */
-function processReserve(ws, reservePub, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- return ws.memoProcessReserve.memo(reservePub, () => __awaiter(this, void 0, void 0, function* () {
- const onOpError = (err) => incrementReserveRetry(ws, reservePub, err);
- yield errors.guardOperationException(() => processReserveImpl(ws, reservePub, forceNow), onOpError);
- }));
- });
-}
-exports.processReserve = processReserve;
-function registerReserveWithBank(ws, reservePub) {
- var _a;
- return __awaiter(this, void 0, void 0, function* () {
- let reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- switch ((_a = reserve) === null || _a === void 0 ? void 0 : _a.reserveStatus) {
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
- break;
- default:
- return;
- }
- const bankStatusUrl = reserve.bankWithdrawStatusUrl;
- if (!bankStatusUrl) {
- return;
- }
- console.log("making selection");
- if (reserve.timestampReserveInfoPosted) {
- throw Error("bank claims that reserve info selection is not done");
- }
- const bankResp = yield ws.http.postJson(bankStatusUrl, {
- reserve_pub: reservePub,
- selected_exchange: reserve.exchangeWire,
- });
- yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, r => {
- switch (r.reserveStatus) {
- case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- break;
- default:
- return;
- }
- r.timestampReserveInfoPosted = time.getTimestampNow();
- r.reserveStatus = dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK;
- r.retryInfo = dbTypes.initRetryInfo();
- return r;
- });
- ws.notify({ type: "wildcard" /* Wildcard */ });
- return processReserveBankStatus(ws, reservePub);
- });
-}
-function processReserveBankStatus(ws, reservePub) {
- return __awaiter(this, void 0, void 0, function* () {
- const onOpError = (err) => incrementReserveRetry(ws, reservePub, err);
- yield errors.guardOperationException(() => processReserveBankStatusImpl(ws, reservePub), onOpError);
- });
-}
-exports.processReserveBankStatus = processReserveBankStatus;
-function processReserveBankStatusImpl(ws, reservePub) {
- var _a;
- return __awaiter(this, void 0, void 0, function* () {
- let reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- switch ((_a = reserve) === null || _a === void 0 ? void 0 : _a.reserveStatus) {
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
- break;
- default:
- return;
- }
- const bankStatusUrl = reserve.bankWithdrawStatusUrl;
- if (!bankStatusUrl) {
- return;
- }
- let status;
- try {
- const statusResp = yield ws.http.get(bankStatusUrl);
- if (statusResp.status !== 200) {
- throw Error(`unexpected status ${statusResp.status} for bank status query`);
- }
- status = talerTypes.codecForWithdrawOperationStatusResponse().decode(yield statusResp.json());
- }
- catch (e) {
- throw e;
- }
- ws.notify({ type: "wildcard" /* Wildcard */ });
- if (status.selection_done) {
- if (reserve.reserveStatus === dbTypes.ReserveRecordStatus.REGISTERING_BANK) {
- yield registerReserveWithBank(ws, reservePub);
- return yield processReserveBankStatus(ws, reservePub);
- }
- }
- else {
- yield registerReserveWithBank(ws, reservePub);
- return yield processReserveBankStatus(ws, reservePub);
- }
- if (status.transfer_done) {
- yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, r => {
- switch (r.reserveStatus) {
- case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- break;
- default:
- return;
- }
- const now = time.getTimestampNow();
- r.timestampConfirmed = now;
- r.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
- r.retryInfo = dbTypes.initRetryInfo();
- return r;
- });
- yield processReserveImpl(ws, reservePub, true);
- }
- else {
- yield ws.db.mutate(dbTypes.Stores.reserves, reservePub, r => {
- switch (r.reserveStatus) {
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- break;
- default:
- return;
- }
- r.bankWithdrawConfirmUrl = status.confirm_transfer_url;
- return r;
- });
- yield incrementReserveRetry(ws, reservePub, undefined);
- }
- ws.notify({ type: "wildcard" /* Wildcard */ });
- });
-}
-function incrementReserveRetry(ws, reservePub, err) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.reserves], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.reserves, reservePub);
- if (!r) {
- return;
- }
- if (!r.retryInfo) {
- return;
- }
- console.log("updating retry info");
- console.log("before", r.retryInfo);
- r.retryInfo.retryCounter++;
- dbTypes.updateRetryInfoTimeout(r.retryInfo);
- console.log("after", r.retryInfo);
- r.lastError = err;
- yield tx.put(dbTypes.Stores.reserves, r);
- }));
- if (err) {
- ws.notify({
- type: "reserve-error" /* ReserveOperationError */,
- operationError: err,
- });
- }
- });
-}
-/**
- * Update the information about a reserve that is stored in the wallet
- * by quering the reserve's exchange.
- */
-function updateReserve(ws, reservePub) {
- return __awaiter(this, void 0, void 0, function* () {
- const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- if (!reserve) {
- throw Error("reserve not in db");
- }
- if (reserve.timestampConfirmed === undefined) {
- throw Error("reserve not confirmed yet");
- }
- if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.QUERYING_STATUS) {
- return;
- }
- const reqUrl = new URL("reserve/status", reserve.exchangeBaseUrl);
- reqUrl.searchParams.set("reserve_pub", reservePub);
- let resp;
- try {
- resp = yield ws.http.get(reqUrl.href);
- console.log("got reserve/status response", yield resp.json());
- if (resp.status === 404) {
- const m = "reserve not known to the exchange yet";
- throw new errors.OperationFailedError(m, {
- type: "waiting",
- message: m,
- details: {},
- });
- }
- if (resp.status !== 200) {
- throw Error(`unexpected status code ${resp.status} for reserve/status`);
- }
- }
- catch (e) {
- logger.trace("caught exception for reserve/status");
- const m = e.message;
- yield incrementReserveRetry(ws, reservePub, {
- type: "network",
- details: {},
- message: m,
- });
- throw new errors.OperationFailedAndReportedError(m);
- }
- const respJson = yield resp.json();
- const reserveInfo = ReserveStatus.codecForReserveStatus().decode(respJson);
- const balance = Amounts.parseOrThrow(reserveInfo.balance);
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.reserves, dbTypes.Stores.reserveUpdatedEvents], (tx) => __awaiter(this, void 0, void 0, function* () {
- const r = yield tx.get(dbTypes.Stores.reserves, reservePub);
- if (!r) {
- return;
- }
- if (r.reserveStatus !== dbTypes.ReserveRecordStatus.QUERYING_STATUS) {
- return;
- }
- const newHistoryTransactions = reserveInfo.history.slice(r.reserveTransactions.length);
- const reserveUpdateId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
- // FIXME: check / compare history!
- if (!r.lastSuccessfulStatusQuery) {
- // FIXME: check if this matches initial expectations
- r.amountWithdrawRemaining = balance;
- const reserveUpdate = {
- reservePub: r.reservePub,
- timestamp: time.getTimestampNow(),
- amountReserveBalance: Amounts.toString(balance),
- amountExpected: Amounts.toString(reserve.amountInitiallyRequested),
- newHistoryTransactions,
- reserveUpdateId,
- };
- yield tx.put(dbTypes.Stores.reserveUpdatedEvents, reserveUpdate);
- }
- else {
- const expectedBalance = Amounts.sub(r.amountWithdrawAllocated, r.amountWithdrawCompleted);
- const cmp = Amounts.cmp(balance, expectedBalance.amount);
- if (cmp == 0) {
- // Nothing changed.
- return;
- }
- if (cmp > 0) {
- const extra = Amounts.sub(balance, expectedBalance.amount).amount;
- r.amountWithdrawRemaining = Amounts.add(r.amountWithdrawRemaining, extra).amount;
- }
- const reserveUpdate = {
- reservePub: r.reservePub,
- timestamp: time.getTimestampNow(),
- amountReserveBalance: Amounts.toString(balance),
- amountExpected: Amounts.toString(expectedBalance.amount),
- newHistoryTransactions,
- reserveUpdateId,
- };
- yield tx.put(dbTypes.Stores.reserveUpdatedEvents, reserveUpdate);
- }
- r.lastSuccessfulStatusQuery = time.getTimestampNow();
- r.reserveStatus = dbTypes.ReserveRecordStatus.WITHDRAWING;
- r.retryInfo = dbTypes.initRetryInfo();
- r.reserveTransactions = reserveInfo.history;
- yield tx.put(dbTypes.Stores.reserves, r);
- }));
- ws.notify({ type: "reserve-updated" /* ReserveUpdated */ });
- });
-}
-function processReserveImpl(ws, reservePub, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
- const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- if (!reserve) {
- console.log("not processing reserve: reserve does not exist");
- return;
- }
- if (!forceNow) {
- const now = time.getTimestampNow();
- if (reserve.retryInfo.nextRetry.t_ms > now.t_ms) {
- logger.trace("processReserve retry not due yet");
- return;
- }
- }
- else {
- yield resetReserveRetry(ws, reservePub);
- }
- logger.trace(`Processing reserve ${reservePub} with status ${reserve.reserveStatus}`);
- switch (reserve.reserveStatus) {
- case dbTypes.ReserveRecordStatus.UNCONFIRMED:
- // nothing to do
- break;
- case dbTypes.ReserveRecordStatus.REGISTERING_BANK:
- yield processReserveBankStatus(ws, reservePub);
- return yield processReserveImpl(ws, reservePub, true);
- case dbTypes.ReserveRecordStatus.QUERYING_STATUS:
- yield updateReserve(ws, reservePub);
- return yield processReserveImpl(ws, reservePub, true);
- case dbTypes.ReserveRecordStatus.WITHDRAWING:
- yield depleteReserve(ws, reservePub);
- break;
- case dbTypes.ReserveRecordStatus.DORMANT:
- // nothing to do
- break;
- case dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK:
- yield processReserveBankStatus(ws, reservePub);
- break;
- default:
- console.warn("unknown reserve record status:", reserve.reserveStatus);
- assertUnreachable_1.assertUnreachable(reserve.reserveStatus);
- break;
- }
- });
-}
-function confirmReserve(ws, req) {
- return __awaiter(this, void 0, void 0, function* () {
- const now = time.getTimestampNow();
- yield ws.db.mutate(dbTypes.Stores.reserves, req.reservePub, reserve => {
- if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.UNCONFIRMED) {
- return;
- }
- reserve.timestampConfirmed = now;
- reserve.reserveStatus = dbTypes.ReserveRecordStatus.QUERYING_STATUS;
- reserve.retryInfo = dbTypes.initRetryInfo();
- return reserve;
- });
- ws.notify({ type: "reserve-updated" /* ReserveUpdated */ });
- processReserve(ws, req.reservePub, true).catch(e => {
- console.log("processing reserve failed:", e);
- });
- });
-}
-exports.confirmReserve = confirmReserve;
-/**
- * Withdraw coins from a reserve until it is empty.
- *
- * When finished, marks the reserve as depleted by setting
- * the depleted timestamp.
- */
-function depleteReserve(ws, reservePub) {
- return __awaiter(this, void 0, void 0, function* () {
- const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- if (!reserve) {
- return;
- }
- if (reserve.reserveStatus !== dbTypes.ReserveRecordStatus.WITHDRAWING) {
- return;
- }
- logger.trace(`depleting reserve ${reservePub}`);
- const withdrawAmount = reserve.amountWithdrawRemaining;
- logger.trace(`getting denom list`);
- const denomsForWithdraw = yield withdraw.getVerifiedWithdrawDenomList(ws, reserve.exchangeBaseUrl, withdrawAmount);
- logger.trace(`got denom list`);
- if (denomsForWithdraw.length === 0) {
- const m = `Unable to withdraw from reserve, no denominations are available to withdraw.`;
- yield incrementReserveRetry(ws, reserve.reservePub, {
- type: "internal",
- message: m,
- details: {},
- });
- console.log(m);
- throw new errors.OperationFailedAndReportedError(m);
- }
- logger.trace("selected denominations");
- const withdrawalSessionId = talerCrypto.encodeCrock(naclFast.randomBytes(32));
- const totalCoinValue = Amounts.sum(denomsForWithdraw.map(x => x.value))
- .amount;
- const withdrawalRecord = {
- withdrawSessionId: withdrawalSessionId,
- exchangeBaseUrl: reserve.exchangeBaseUrl,
- source: {
- type: "reserve",
- reservePub: reserve.reservePub,
- },
- rawWithdrawalAmount: withdrawAmount,
- timestampStart: time.getTimestampNow(),
- denoms: denomsForWithdraw.map(x => x.denomPub),
- withdrawn: denomsForWithdraw.map(x => false),
- planchets: denomsForWithdraw.map(x => undefined),
- totalCoinValue,
- retryInfo: dbTypes.initRetryInfo(),
- lastErrorPerCoin: {},
- lastError: undefined,
- };
- const totalCoinWithdrawFee = Amounts.sum(denomsForWithdraw.map(x => x.feeWithdraw)).amount;
- const totalWithdrawAmount = Amounts.add(totalCoinValue, totalCoinWithdrawFee)
- .amount;
- function mutateReserve(r) {
- const remaining = Amounts.sub(r.amountWithdrawRemaining, totalWithdrawAmount);
- if (remaining.saturated) {
- console.error("can't create planchets, saturated");
- throw query.TransactionAbort;
- }
- const allocated = Amounts.add(r.amountWithdrawAllocated, totalWithdrawAmount);
- if (allocated.saturated) {
- console.error("can't create planchets, saturated");
- throw query.TransactionAbort;
- }
- r.amountWithdrawRemaining = remaining.amount;
- r.amountWithdrawAllocated = allocated.amount;
- r.reserveStatus = dbTypes.ReserveRecordStatus.DORMANT;
- r.retryInfo = dbTypes.initRetryInfo(false);
- return r;
- }
- const success = yield ws.db.runWithWriteTransaction([dbTypes.Stores.withdrawalSession, dbTypes.Stores.reserves], (tx) => __awaiter(this, void 0, void 0, function* () {
- const myReserve = yield tx.get(dbTypes.Stores.reserves, reservePub);
- if (!myReserve) {
- return false;
- }
- if (myReserve.reserveStatus !== dbTypes.ReserveRecordStatus.WITHDRAWING) {
- return false;
- }
- yield tx.mutate(dbTypes.Stores.reserves, reserve.reservePub, mutateReserve);
- yield tx.put(dbTypes.Stores.withdrawalSession, withdrawalRecord);
- return true;
- }));
- if (success) {
- console.log("processing new withdraw session");
- ws.notify({
- type: "withdraw-session-created" /* WithdrawSessionCreated */,
- withdrawSessionId: withdrawalSessionId,
- });
- yield withdraw.processWithdrawSession(ws, withdrawalSessionId);
- }
- else {
- console.trace("withdraw session already existed");
- }
- });
-}
-function createTalerWithdrawReserve(ws, talerWithdrawUri, selectedExchange) {
- return __awaiter(this, void 0, void 0, function* () {
- const withdrawInfo = yield withdraw.getBankWithdrawalInfo(ws, talerWithdrawUri);
- const exchangeWire = yield exchanges.getExchangePaytoUri(ws, selectedExchange, withdrawInfo.wireTypes);
- const reserve = yield createReserve(ws, {
- amount: withdrawInfo.amount,
- bankWithdrawStatusUrl: withdrawInfo.extractedStatusUrl,
- exchange: selectedExchange,
- senderWire: withdrawInfo.senderWire,
- exchangeWire: exchangeWire,
- });
- // We do this here, as the reserve should be registered before we return,
- // so that we can redirect the user to the bank's status page.
- yield processReserveBankStatus(ws, reserve.reservePub);
- console.log("acceptWithdrawal: returning");
- return {
- reservePub: reserve.reservePub,
- confirmTransferUrl: withdrawInfo.confirmTransferUrl,
- };
- });
-}
-exports.createTalerWithdrawReserve = createTalerWithdrawReserve;
-
-});
-
-unwrapExports(reserves);
-var reserves_1 = reserves.createReserve;
-var reserves_2 = reserves.processReserve;
-var reserves_3 = reserves.processReserveBankStatus;
-var reserves_4 = reserves.confirmReserve;
-var reserves_5 = reserves.createTalerWithdrawReserve;
-
-var timer = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", { value: true });
class IntervalHandle {
constructor(h) {
@@ -11140,9 +11149,12 @@ exports.performanceNow = (() => {
return t[0] * 1e9 + t[1];
};
}
- else {
+ else if (typeof performance !== "undefined") {
return () => performance.now();
}
+ else {
+ return () => 0;
+ }
})();
/**
* Call a function every time the delay given in milliseconds passes.
@@ -11251,15 +11263,9 @@ var cryptoApi = createCommonjsModule(function (module, exports) {
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 __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const timer$1 = __importStar(timer);
+
+const timer$1 = tslib_1.__importStar(timer);
/**
* Number of different priorities. Each priority p
* must be 0 <= p < NUM_PRIO.
@@ -11268,7 +11274,7 @@ const NUM_PRIO = 5;
class BrowserCryptoWorkerFactory {
startWorker() {
const workerCtor = Worker;
- const workerPath = "/dist/cryptoWorker-bundle.js";
+ const workerPath = "/dist/webextension/browserWorkerEntry.js";
return new workerCtor(workerPath);
}
getConcurrency() {
@@ -11319,7 +11325,7 @@ class CryptoApi {
* Terminate all worker threads.
*/
terminateWorkers() {
- for (let worker of this.workers) {
+ for (const worker of this.workers) {
if (worker.w) {
CryptoApi.enableTracing && console.log("terminating worker");
worker.w.terminate();
@@ -11354,11 +11360,15 @@ class CryptoApi {
}
ws.currentWorkItem = work;
this.numBusy++;
+ let worker;
if (!ws.w) {
- const w = this.workerFactory.startWorker();
- w.onmessage = (m) => this.handleWorkerMessage(ws, m);
- w.onerror = (e) => this.handleWorkerError(ws, e);
- ws.w = w;
+ worker = this.workerFactory.startWorker();
+ worker.onmessage = (m) => this.handleWorkerMessage(ws, m);
+ worker.onerror = (e) => this.handleWorkerError(ws, e);
+ ws.w = worker;
+ }
+ else {
+ worker = ws.w;
}
const msg = {
args: work.args,
@@ -11367,7 +11377,7 @@ class CryptoApi {
};
this.resetWorkerTimeout(ws);
work.startTime = timer$1.performanceNow();
- setImmediate(() => ws.w.postMessage(msg));
+ setTimeout(() => worker.postMessage(msg), 0);
}
resetWorkerTimeout(ws) {
if (ws.terminationTimerHandle !== null) {
@@ -11392,8 +11402,10 @@ class CryptoApi {
}
console.error(e.message);
try {
- ws.w.terminate();
- ws.w = null;
+ if (ws.w) {
+ ws.w.terminate();
+ ws.w = null;
+ }
}
catch (e) {
console.error(e);
@@ -11411,6 +11423,9 @@ class CryptoApi {
const q = this.workQueues[NUM_PRIO - i - 1];
if (q.length !== 0) {
const work = q.shift();
+ if (!work) {
+ continue;
+ }
this.wake(ws, work);
return;
}
@@ -11435,8 +11450,7 @@ class CryptoApi {
return;
}
CryptoApi.enableTracing &&
- console.log(`rpc ${currentWorkItem.operation} took ${timer$1.performanceNow() -
- currentWorkItem.startTime}ms`);
+ console.log(`rpc ${currentWorkItem.operation} took ${timer$1.performanceNow() - currentWorkItem.startTime}ms`);
currentWorkItem.resolve(msg.data.result);
}
doRpc(operation, priority, ...args) {
@@ -11478,8 +11492,8 @@ class CryptoApi {
hashString(str) {
return this.doRpc("hashString", 1, str);
}
- hashDenomPub(denomPub) {
- return this.doRpc("hashDenomPub", 1, denomPub);
+ hashEncoded(encodedBytes) {
+ return this.doRpc("hashEncoded", 1, encodedBytes);
}
isValidDenom(denom, masterPub) {
return this.doRpc("isValidDenom", 2, denom, masterPub);
@@ -11505,8 +11519,8 @@ class CryptoApi {
isValidWireAccount(paytoUri, sig, masterPub) {
return this.doRpc("isValidWireAccount", 4, paytoUri, sig, masterPub);
}
- createPaybackRequest(coin) {
- return this.doRpc("createPaybackRequest", 1, coin);
+ createRecoupRequest(coin) {
+ return this.doRpc("createRecoupRequest", 1, coin);
}
createRefreshSession(exchangeBaseUrl, kappa, meltCoin, newCoinDenoms, meltFee) {
return this.doRpc("createRefreshSession", 4, exchangeBaseUrl, kappa, meltCoin, newCoinDenoms, meltFee);
@@ -11647,6 +11661,7 @@ class InternalWalletState {
this.memoGetPending = new asyncMemo.AsyncOpMemoSingle();
this.memoGetBalance = new asyncMemo.AsyncOpMemoSingle();
this.memoProcessRefresh = new asyncMemo.AsyncOpMemoMap();
+ this.memoProcessRecoup = new asyncMemo.AsyncOpMemoMap();
this.listeners = [];
this.cryptoApi = new cryptoApi.CryptoApi(cryptoWorkerFactory);
}
@@ -11654,9 +11669,9 @@ class InternalWalletState {
logger.trace("Notification", n);
for (const l of this.listeners) {
const nc = JSON.parse(JSON.stringify(n));
- setImmediate(() => {
+ setTimeout(() => {
l(nc);
- });
+ }, 0);
}
}
addNotificationListener(f) {
@@ -11686,32 +11701,18 @@ var history = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+
+
/**
* Create an event ID from the type and the primary key for the event.
*/
function makeEventId(type, ...args) {
- return type + ";" + args.map(x => encodeURIComponent(x)).join(";");
+ return type + ";" + args.map((x) => encodeURIComponent(x)).join(";");
}
function getOrderShortInfo(proposal) {
const download = proposal.download;
@@ -11719,7 +11720,7 @@ function getOrderShortInfo(proposal) {
return undefined;
}
return {
- amount: Amounts.toString(download.contractData.amount),
+ amount: amounts.Amounts.stringify(download.contractData.amount),
fulfillmentUrl: download.contractData.fulfillmentUrl,
orderId: download.contractData.orderId,
merchantBaseUrl: download.contractData.merchantBaseUrl,
@@ -11728,8 +11729,8 @@ function getOrderShortInfo(proposal) {
};
}
function collectProposalHistory(tx, history, historyQuery) {
- return __awaiter(this, void 0, void 0, function* () {
- tx.iter(dbTypes.Stores.proposals).forEachAsync((proposal) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ tx.iter(dbTypes.Stores.proposals).forEachAsync((proposal) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const status = proposal.proposalStatus;
switch (status) {
case "accepted" /* ACCEPTED */:
@@ -11797,7 +11798,7 @@ function collectProposalHistory(tx, history, historyQuery) {
* Retrive the full event history for this wallet.
*/
function getHistory(ws, historyQuery) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const history = [];
// FIXME: do pagination instead of generating the full history
// We uniquely identify history rows via their timestamp.
@@ -11814,12 +11815,13 @@ function getHistory(ws, historyQuery) {
dbTypes.Stores.refreshGroups,
dbTypes.Stores.reserves,
dbTypes.Stores.tips,
- dbTypes.Stores.withdrawalSession,
+ dbTypes.Stores.withdrawalGroups,
dbTypes.Stores.payEvents,
dbTypes.Stores.refundEvents,
dbTypes.Stores.reserveUpdatedEvents,
- ], (tx) => __awaiter(this, void 0, void 0, function* () {
- tx.iter(dbTypes.Stores.exchanges).forEach(exchange => {
+ dbTypes.Stores.recoupGroups,
+ ], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ tx.iter(dbTypes.Stores.exchanges).forEach((exchange) => {
history.push({
type: "exchange-added" /* ExchangeAdded */,
builtIn: false,
@@ -11828,7 +11830,7 @@ function getHistory(ws, historyQuery) {
timestamp: exchange.timestampAdded,
});
});
- tx.iter(dbTypes.Stores.exchangeUpdatedEvents).forEach(eu => {
+ tx.iter(dbTypes.Stores.exchangeUpdatedEvents).forEach((eu) => {
history.push({
type: "exchange-updated" /* ExchangeUpdated */,
eventId: makeEventId("exchange-updated" /* ExchangeUpdated */, eu.exchangeBaseUrl),
@@ -11836,8 +11838,7 @@ function getHistory(ws, historyQuery) {
timestamp: eu.timestamp,
});
});
- tx.iter(dbTypes.Stores.withdrawalSession).forEach(wsr => {
- var _a;
+ tx.iter(dbTypes.Stores.withdrawalGroups).forEach((wsr) => {
if (wsr.timestampFinish) {
const cs = [];
wsr.planchets.forEach((x) => {
@@ -11846,20 +11847,20 @@ function getHistory(ws, historyQuery) {
}
});
let verboseDetails = undefined;
- if ((_a = historyQuery) === null || _a === void 0 ? void 0 : _a.verboseDetails) {
+ if (historyQuery === null || historyQuery === void 0 ? void 0 : historyQuery.extraDebug) {
verboseDetails = {
coins: cs.map((x) => ({
- value: Amounts.toString(x.coinValue),
+ value: amounts.Amounts.stringify(x.coinValue),
denomPub: x.denomPub,
})),
};
}
history.push({
type: "withdrawn" /* Withdrawn */,
- withdrawSessionId: wsr.withdrawSessionId,
- eventId: makeEventId("withdrawn" /* Withdrawn */, wsr.withdrawSessionId),
- amountWithdrawnEffective: Amounts.toString(wsr.totalCoinValue),
- amountWithdrawnRaw: Amounts.toString(wsr.rawWithdrawalAmount),
+ withdrawalGroupId: wsr.withdrawalGroupId,
+ eventId: makeEventId("withdrawn" /* Withdrawn */, wsr.withdrawalGroupId),
+ amountWithdrawnEffective: amounts.Amounts.stringify(wsr.totalCoinValue),
+ amountWithdrawnRaw: amounts.Amounts.stringify(wsr.rawWithdrawalAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
timestamp: wsr.timestampFinish,
withdrawalSource: wsr.source,
@@ -11868,8 +11869,7 @@ function getHistory(ws, historyQuery) {
}
});
yield collectProposalHistory(tx, history);
- yield tx.iter(dbTypes.Stores.payEvents).forEachAsync((pe) => __awaiter(this, void 0, void 0, function* () {
- var _a;
+ yield tx.iter(dbTypes.Stores.payEvents).forEachAsync((pe) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const proposal = yield tx.get(dbTypes.Stores.proposals, pe.proposalId);
if (!proposal) {
return;
@@ -11883,7 +11883,7 @@ function getHistory(ws, historyQuery) {
return;
}
let verboseDetails = undefined;
- if ((_a = historyQuery) === null || _a === void 0 ? void 0 : _a.verboseDetails) {
+ if (historyQuery === null || historyQuery === void 0 ? void 0 : historyQuery.extraDebug) {
const coins = [];
for (const x of purchase.payReq.coins) {
const c = yield tx.get(dbTypes.Stores.coins, x.coin_pub);
@@ -11891,7 +11891,10 @@ function getHistory(ws, historyQuery) {
// FIXME: what to do here??
continue;
}
- const d = yield tx.get(dbTypes.Stores.denominations, [c.exchangeBaseUrl, c.denomPub]);
+ const d = yield tx.get(dbTypes.Stores.denominations, [
+ c.exchangeBaseUrl,
+ c.denomPub,
+ ]);
if (!d) {
// FIXME: what to do here??
continue;
@@ -11899,12 +11902,12 @@ function getHistory(ws, historyQuery) {
coins.push({
contribution: x.contribution,
denomPub: c.denomPub,
- value: Amounts.toString(d.value),
+ value: amounts.Amounts.stringify(d.value),
});
}
verboseDetails = { coins };
}
- const amountPaidWithFees = Amounts.sum(purchase.payReq.coins.map(x => Amounts.parseOrThrow(x.contribution))).amount;
+ const amountPaidWithFees = amounts.Amounts.sum(purchase.payReq.coins.map((x) => amounts.Amounts.parseOrThrow(x.contribution))).amount;
history.push({
type: "payment-sent" /* PaymentSent */,
eventId: makeEventId("payment-sent" /* PaymentSent */, pe.proposalId),
@@ -11913,12 +11916,11 @@ function getHistory(ws, historyQuery) {
sessionId: pe.sessionId,
timestamp: pe.timestamp,
numCoins: purchase.payReq.coins.length,
- amountPaidWithFees: Amounts.toString(amountPaidWithFees),
+ amountPaidWithFees: amounts.Amounts.stringify(amountPaidWithFees),
verboseDetails,
});
}));
- yield tx.iter(dbTypes.Stores.refreshGroups).forEachAsync((rg) => __awaiter(this, void 0, void 0, function* () {
- var _b;
+ yield tx.iter(dbTypes.Stores.refreshGroups).forEachAsync((rg) => tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!rg.timestampFinished) {
return;
}
@@ -11945,16 +11947,16 @@ function getHistory(ws, historyQuery) {
amountsRaw.push(c.currentAmount);
}
}
- let amountRefreshedRaw = Amounts.sum(amountsRaw).amount;
+ const amountRefreshedRaw = amounts.Amounts.sum(amountsRaw).amount;
let amountRefreshedEffective;
if (amountsEffective.length == 0) {
- amountRefreshedEffective = Amounts.getZero(amountRefreshedRaw.currency);
+ amountRefreshedEffective = amounts.Amounts.getZero(amountRefreshedRaw.currency);
}
else {
- amountRefreshedEffective = Amounts.sum(amountsEffective).amount;
+ amountRefreshedEffective = amounts.Amounts.sum(amountsEffective).amount;
}
let verboseDetails = undefined;
- if ((_b = historyQuery) === null || _b === void 0 ? void 0 : _b.verboseDetails) {
+ if (historyQuery === null || historyQuery === void 0 ? void 0 : historyQuery.extraDebug) {
const outputCoins = [];
for (const rs of rg.refreshSessionPerCoin) {
if (!rs) {
@@ -11964,13 +11966,16 @@ function getHistory(ws, historyQuery) {
if (!nd) {
continue;
}
- const d = yield tx.get(dbTypes.Stores.denominations, [rs.exchangeBaseUrl, nd]);
+ const d = yield tx.get(dbTypes.Stores.denominations, [
+ rs.exchangeBaseUrl,
+ nd,
+ ]);
if (!d) {
continue;
}
outputCoins.push({
denomPub: d.denomPub,
- value: Amounts.toString(d.value),
+ value: amounts.Amounts.stringify(d.value),
});
}
}
@@ -11984,15 +11989,15 @@ function getHistory(ws, historyQuery) {
eventId: makeEventId("refreshed" /* Refreshed */, rg.refreshGroupId),
timestamp: rg.timestampFinished,
refreshReason: rg.reason,
- amountRefreshedEffective: Amounts.toString(amountRefreshedEffective),
- amountRefreshedRaw: Amounts.toString(amountRefreshedRaw),
+ amountRefreshedEffective: amounts.Amounts.stringify(amountRefreshedEffective),
+ amountRefreshedRaw: amounts.Amounts.stringify(amountRefreshedRaw),
numInputCoins,
numOutputCoins,
numRefreshedInputCoins,
verboseDetails,
});
}));
- tx.iter(dbTypes.Stores.reserveUpdatedEvents).forEachAsync((ru) => __awaiter(this, void 0, void 0, function* () {
+ tx.iter(dbTypes.Stores.reserveUpdatedEvents).forEachAsync((ru) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const reserve = yield tx.get(dbTypes.Stores.reserves, ru.reservePub);
if (!reserve) {
return;
@@ -12009,32 +12014,33 @@ function getHistory(ws, historyQuery) {
type: "manual" /* Manual */,
};
}
+ const s = reserveHistoryUtil.summarizeReserveHistory(reserve.reserveTransactions, reserve.currency);
history.push({
type: "reserve-balance-updated" /* ReserveBalanceUpdated */,
eventId: makeEventId("reserve-balance-updated" /* ReserveBalanceUpdated */, ru.reserveUpdateId),
- amountExpected: ru.amountExpected,
- amountReserveBalance: ru.amountReserveBalance,
timestamp: ru.timestamp,
- newHistoryTransactions: ru.newHistoryTransactions,
reserveShortInfo: {
exchangeBaseUrl: reserve.exchangeBaseUrl,
reserveCreationDetail,
reservePub: reserve.reservePub,
},
+ reserveAwaitedAmount: amounts.Amounts.stringify(s.awaitedReserveAmount),
+ reserveBalance: amounts.Amounts.stringify(s.computedReserveBalance),
+ reserveUnclaimedAmount: amounts.Amounts.stringify(s.unclaimedReserveAmount),
});
}));
- tx.iter(dbTypes.Stores.tips).forEach(tip => {
+ tx.iter(dbTypes.Stores.tips).forEach((tip) => {
if (tip.acceptedTimestamp) {
history.push({
type: "tip-accepted" /* TipAccepted */,
eventId: makeEventId("tip-accepted" /* TipAccepted */, tip.tipId),
timestamp: tip.acceptedTimestamp,
tipId: tip.tipId,
- tipAmountRaw: Amounts.toString(tip.amount),
+ tipAmountRaw: amounts.Amounts.stringify(tip.amount),
});
}
});
- tx.iter(dbTypes.Stores.refundEvents).forEachAsync((re) => __awaiter(this, void 0, void 0, function* () {
+ tx.iter(dbTypes.Stores.refundEvents).forEachAsync((re) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const proposal = yield tx.get(dbTypes.Stores.proposals, re.proposalId);
if (!proposal) {
return;
@@ -12048,31 +12054,31 @@ function getHistory(ws, historyQuery) {
return;
}
const purchaseAmount = purchase.contractData.amount;
- let amountRefundedRaw = Amounts.getZero(purchaseAmount.currency);
- let amountRefundedInvalid = Amounts.getZero(purchaseAmount.currency);
- let amountRefundedEffective = Amounts.getZero(purchaseAmount.currency);
+ let amountRefundedRaw = amounts.Amounts.getZero(purchaseAmount.currency);
+ let amountRefundedInvalid = amounts.Amounts.getZero(purchaseAmount.currency);
+ let amountRefundedEffective = amounts.Amounts.getZero(purchaseAmount.currency);
Object.keys(purchase.refundState.refundsDone).forEach((x, i) => {
const r = purchase.refundState.refundsDone[x];
if (r.refundGroupId !== re.refundGroupId) {
return;
}
- const refundAmount = Amounts.parseOrThrow(r.perm.refund_amount);
- const refundFee = Amounts.parseOrThrow(r.perm.refund_fee);
- amountRefundedRaw = Amounts.add(amountRefundedRaw, refundAmount)
+ const refundAmount = amounts.Amounts.parseOrThrow(r.perm.refund_amount);
+ const refundFee = amounts.Amounts.parseOrThrow(r.perm.refund_fee);
+ amountRefundedRaw = amounts.Amounts.add(amountRefundedRaw, refundAmount)
.amount;
- amountRefundedEffective = Amounts.add(amountRefundedEffective, refundAmount).amount;
- amountRefundedEffective = Amounts.sub(amountRefundedEffective, refundFee).amount;
+ amountRefundedEffective = amounts.Amounts.add(amountRefundedEffective, refundAmount).amount;
+ amountRefundedEffective = amounts.Amounts.sub(amountRefundedEffective, refundFee).amount;
});
Object.keys(purchase.refundState.refundsFailed).forEach((x, i) => {
const r = purchase.refundState.refundsFailed[x];
if (r.refundGroupId !== re.refundGroupId) {
return;
}
- const ra = Amounts.parseOrThrow(r.perm.refund_amount);
- const refundFee = Amounts.parseOrThrow(r.perm.refund_fee);
- amountRefundedRaw = Amounts.add(amountRefundedRaw, ra).amount;
- amountRefundedInvalid = Amounts.add(amountRefundedInvalid, ra).amount;
- amountRefundedEffective = Amounts.sub(amountRefundedEffective, refundFee).amount;
+ const ra = amounts.Amounts.parseOrThrow(r.perm.refund_amount);
+ const refundFee = amounts.Amounts.parseOrThrow(r.perm.refund_fee);
+ amountRefundedRaw = amounts.Amounts.add(amountRefundedRaw, ra).amount;
+ amountRefundedInvalid = amounts.Amounts.add(amountRefundedInvalid, ra).amount;
+ amountRefundedEffective = amounts.Amounts.sub(amountRefundedEffective, refundFee).amount;
});
history.push({
type: "refund" /* Refund */,
@@ -12080,11 +12086,28 @@ function getHistory(ws, historyQuery) {
refundGroupId: re.refundGroupId,
orderShortInfo,
timestamp: re.timestamp,
- amountRefundedEffective: Amounts.toString(amountRefundedEffective),
- amountRefundedRaw: Amounts.toString(amountRefundedRaw),
- amountRefundedInvalid: Amounts.toString(amountRefundedInvalid),
+ amountRefundedEffective: amounts.Amounts.stringify(amountRefundedEffective),
+ amountRefundedRaw: amounts.Amounts.stringify(amountRefundedRaw),
+ amountRefundedInvalid: amounts.Amounts.stringify(amountRefundedInvalid),
});
}));
+ tx.iter(dbTypes.Stores.recoupGroups).forEach((rg) => {
+ if (rg.timestampFinished) {
+ let verboseDetails = undefined;
+ if (historyQuery === null || historyQuery === void 0 ? void 0 : historyQuery.extraDebug) {
+ verboseDetails = {
+ oldAmountPerCoin: rg.oldAmountPerCoin.map(amounts.Amounts.stringify),
+ };
+ }
+ history.push({
+ type: "funds-recouped" /* FundsRecouped */,
+ timestamp: rg.timestampFinished,
+ eventId: makeEventId("funds-recouped" /* FundsRecouped */, rg.recoupGroupId),
+ numCoinsRecouped: rg.coinPubs.length,
+ verboseDetails,
+ });
+ }
+ });
}));
history.sort((h1, h2) => time.timestampCmp(h1.timestamp, h2.timestamp));
return { history };
@@ -12097,7 +12120,7 @@ exports.getHistory = getHistory;
unwrapExports(history);
var history_1 = history.getHistory;
-var pending = createCommonjsModule(function (module, exports) {
+var balance = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
(C) 2019 GNUnet e.V.
@@ -12113,33 +12136,154 @@ var pending = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+const Amounts = tslib_1.__importStar(amounts);
+
+const logger = new logging.Logger("withdraw.ts");
+/**
+ * Get balance information.
+ */
+function getBalancesInsideTransaction(ws, tx) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ /**
+ * Add amount to a balance field, both for
+ * the slicing by exchange and currency.
+ */
+ function addTo(balance, field, amount, exchange) {
+ const z = Amounts.getZero(amount.currency);
+ const balanceIdentity = {
+ available: z,
+ paybackAmount: z,
+ pendingIncoming: z,
+ pendingPayment: z,
+ pendingIncomingDirty: z,
+ pendingIncomingRefresh: z,
+ pendingIncomingWithdraw: z,
+ };
+ let entryCurr = balance.byCurrency[amount.currency];
+ if (!entryCurr) {
+ balance.byCurrency[amount.currency] = entryCurr = Object.assign({}, balanceIdentity);
+ }
+ let entryEx = balance.byExchange[exchange];
+ if (!entryEx) {
+ balance.byExchange[exchange] = entryEx = Object.assign({}, balanceIdentity);
+ }
+ entryCurr[field] = Amounts.add(entryCurr[field], amount).amount;
+ entryEx[field] = Amounts.add(entryEx[field], amount).amount;
+ }
+ const balanceStore = {
+ byCurrency: {},
+ byExchange: {},
+ };
+ yield tx.iter(dbTypes.Stores.coins).forEach((c) => {
+ if (c.suspended) {
+ return;
+ }
+ if (c.status === "fresh" /* Fresh */) {
+ addTo(balanceStore, "available", c.currentAmount, c.exchangeBaseUrl);
+ }
+ });
+ yield tx.iter(dbTypes.Stores.refreshGroups).forEach((r) => {
+ // Don't count finished refreshes, since the refresh already resulted
+ // in coins being added to the wallet.
+ if (r.timestampFinished) {
+ return;
+ }
+ for (let i = 0; i < r.oldCoinPubs.length; i++) {
+ const session = r.refreshSessionPerCoin[i];
+ if (session) {
+ addTo(balanceStore, "pendingIncoming", session.amountRefreshOutput, session.exchangeBaseUrl);
+ addTo(balanceStore, "pendingIncomingRefresh", session.amountRefreshOutput, session.exchangeBaseUrl);
+ }
+ }
+ });
+ yield tx.iter(dbTypes.Stores.withdrawalGroups).forEach((wds) => {
+ let w = wds.totalCoinValue;
+ for (let i = 0; i < wds.planchets.length; i++) {
+ if (wds.withdrawn[i]) {
+ const p = wds.planchets[i];
+ if (p) {
+ w = Amounts.sub(w, p.coinValue).amount;
+ }
+ }
+ }
+ addTo(balanceStore, "pendingIncoming", w, wds.exchangeBaseUrl);
+ });
+ yield tx.iter(dbTypes.Stores.purchases).forEach((t) => {
+ if (t.timestampFirstSuccessfulPay) {
+ return;
+ }
+ for (const c of t.payReq.coins) {
+ addTo(balanceStore, "pendingPayment", Amounts.parseOrThrow(c.contribution), c.exchange_url);
+ }
+ });
+ return balanceStore;
});
-};
+}
+exports.getBalancesInsideTransaction = getBalancesInsideTransaction;
+/**
+ * Get detailed balance information, sliced by exchange and by currency.
+ */
+function getBalances(ws) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ logger.trace("starting to compute balance");
+ return yield ws.db.runWithReadTransaction([
+ dbTypes.Stores.coins,
+ dbTypes.Stores.refreshGroups,
+ dbTypes.Stores.reserves,
+ dbTypes.Stores.purchases,
+ dbTypes.Stores.withdrawalGroups,
+ ], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ return getBalancesInsideTransaction(ws, tx);
+ }));
+ });
+}
+exports.getBalances = getBalances;
+
+});
+
+unwrapExports(balance);
+var balance_1 = balance.getBalancesInsideTransaction;
+var balance_2 = balance.getBalances;
+
+var pending = createCommonjsModule(function (module, exports) {
+/*
+ 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/>
+ */
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Imports.
*/
+
function updateRetryDelay(oldDelay, now, retryTimestamp) {
const remaining = time.getDurationRemaining(retryTimestamp, now);
const nextDelay = time.durationMin(oldDelay, remaining);
return nextDelay;
}
function gatherExchangePending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (onlyDue) {
// FIXME: exchanges should also be updated regularly
return;
}
- yield tx.iter(dbTypes.Stores.exchanges).forEach(e => {
+ yield tx.iter(dbTypes.Stores.exchanges).forEach((e) => {
switch (e.updateStatus) {
case "finished" /* Finished */:
if (e.lastError) {
@@ -12177,7 +12321,7 @@ function gatherExchangePending(tx, now, resp, onlyDue = false) {
resp.pendingOperations.push({
type: "exchange-update" /* ExchangeUpdate */,
givesLifeness: false,
- stage: "fetch-keys",
+ stage: "fetch-keys" /* FetchKeys */,
exchangeBaseUrl: e.baseUrl,
lastError: e.lastError,
reason: e.updateReason || "unknown",
@@ -12187,7 +12331,7 @@ function gatherExchangePending(tx, now, resp, onlyDue = false) {
resp.pendingOperations.push({
type: "exchange-update" /* ExchangeUpdate */,
givesLifeness: false,
- stage: "fetch-wire",
+ stage: "fetch-wire" /* FetchWire */,
exchangeBaseUrl: e.baseUrl,
lastError: e.lastError,
reason: e.updateReason || "unknown",
@@ -12197,7 +12341,7 @@ function gatherExchangePending(tx, now, resp, onlyDue = false) {
resp.pendingOperations.push({
type: "exchange-update" /* ExchangeUpdate */,
givesLifeness: false,
- stage: "finalize-update",
+ stage: "finalize-update" /* FinalizeUpdate */,
exchangeBaseUrl: e.baseUrl,
lastError: e.lastError,
reason: e.updateReason || "unknown",
@@ -12219,10 +12363,12 @@ function gatherExchangePending(tx, now, resp, onlyDue = false) {
});
}
function gatherReservePending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
// FIXME: this should be optimized by using an index for "onlyDue==true".
- yield tx.iter(dbTypes.Stores.reserves).forEach(reserve => {
- const reserveType = reserve.bankWithdrawStatusUrl ? "taler-bank" : "manual";
+ yield tx.iter(dbTypes.Stores.reserves).forEach((reserve) => {
+ const reserveType = reserve.bankWithdrawStatusUrl
+ ? "taler-bank-withdraw" /* TalerBankWithdraw */
+ : "manual" /* Manual */;
if (!reserve.retryInfo.active) {
return;
}
@@ -12278,8 +12424,8 @@ function gatherReservePending(tx, now, resp, onlyDue = false) {
});
}
function gatherRefreshPending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.refreshGroups).forEach(r => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.refreshGroups).forEach((r) => {
if (r.timestampFinished) {
return;
}
@@ -12298,8 +12444,8 @@ function gatherRefreshPending(tx, now, resp, onlyDue = false) {
});
}
function gatherWithdrawalPending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.withdrawalSession).forEach(wsr => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.withdrawalGroups).forEach((wsr) => {
if (wsr.timestampFinish) {
return;
}
@@ -12315,25 +12461,37 @@ function gatherWithdrawalPending(tx, now, resp, onlyDue = false) {
numCoinsTotal,
numCoinsWithdrawn,
source: wsr.source,
- withdrawSessionId: wsr.withdrawSessionId,
+ withdrawalGroupId: wsr.withdrawalGroupId,
+ lastError: wsr.lastError,
});
});
});
}
function gatherProposalPending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.proposals).forEach(proposal => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.proposals).forEach((proposal) => {
if (proposal.proposalStatus == "proposed" /* PROPOSED */) {
if (onlyDue) {
return;
}
- resp.pendingOperations.push({
- type: "proposal-choice" /* ProposalChoice */,
- givesLifeness: false,
- merchantBaseUrl: proposal.download.contractData.merchantBaseUrl,
- proposalId: proposal.proposalId,
- proposalTimestamp: proposal.timestamp,
- });
+ const dl = proposal.download;
+ if (!dl) {
+ resp.pendingOperations.push({
+ type: "bug" /* Bug */,
+ message: "proposal is in invalid state",
+ details: {},
+ givesLifeness: false,
+ });
+ }
+ else {
+ resp.pendingOperations.push({
+ type: "proposal-choice" /* ProposalChoice */,
+ givesLifeness: false,
+ merchantBaseUrl: dl.contractData.merchantBaseUrl,
+ proposalId: proposal.proposalId,
+ proposalTimestamp: proposal.timestamp,
+ });
+ }
}
else if (proposal.proposalStatus == "downloading" /* DOWNLOADING */) {
resp.nextRetryDelay = updateRetryDelay(resp.nextRetryDelay, now, proposal.retryInfo.nextRetry);
@@ -12355,8 +12513,8 @@ function gatherProposalPending(tx, now, resp, onlyDue = false) {
});
}
function gatherTipPending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.tips).forEach(tip => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.tips).forEach((tip) => {
if (tip.pickedUp) {
return;
}
@@ -12377,8 +12535,8 @@ function gatherTipPending(tx, now, resp, onlyDue = false) {
});
}
function gatherPurchasePending(tx, now, resp, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.purchases).forEach(pr => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.purchases).forEach((pr) => {
if (pr.paymentSubmitPending) {
resp.nextRetryDelay = updateRetryDelay(resp.nextRetryDelay, now, pr.payRetryInfo.nextRetry);
if (!onlyDue || pr.payRetryInfo.nextRetry.t_ms <= now.t_ms) {
@@ -12423,24 +12581,47 @@ function gatherPurchasePending(tx, now, resp, onlyDue = false) {
});
});
}
-function getPendingOperations(ws, onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- const resp = {
- nextRetryDelay: { d_ms: Number.MAX_SAFE_INTEGER },
- onlyDue: onlyDue,
- pendingOperations: [],
- };
+function gatherRecoupPending(tx, now, resp, onlyDue = false) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield tx.iter(dbTypes.Stores.recoupGroups).forEach((rg) => {
+ if (rg.timestampFinished) {
+ return;
+ }
+ resp.nextRetryDelay = updateRetryDelay(resp.nextRetryDelay, now, rg.retryInfo.nextRetry);
+ if (onlyDue && rg.retryInfo.nextRetry.t_ms > now.t_ms) {
+ return;
+ }
+ resp.pendingOperations.push({
+ type: "recoup" /* Recoup */,
+ givesLifeness: true,
+ recoupGroupId: rg.recoupGroupId,
+ retryInfo: rg.retryInfo,
+ lastError: rg.lastError,
+ });
+ });
+ });
+}
+function getPendingOperations(ws, { onlyDue = false } = {}) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const now = time.getTimestampNow();
- yield ws.db.runWithReadTransaction([
+ return yield ws.db.runWithReadTransaction([
dbTypes.Stores.exchanges,
dbTypes.Stores.reserves,
dbTypes.Stores.refreshGroups,
dbTypes.Stores.coins,
- dbTypes.Stores.withdrawalSession,
+ dbTypes.Stores.withdrawalGroups,
dbTypes.Stores.proposals,
dbTypes.Stores.tips,
dbTypes.Stores.purchases,
- ], (tx) => __awaiter(this, void 0, void 0, function* () {
+ dbTypes.Stores.recoupGroups,
+ ], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const walletBalance = yield balance.getBalancesInsideTransaction(ws, tx);
+ const resp = {
+ nextRetryDelay: { d_ms: Number.MAX_SAFE_INTEGER },
+ onlyDue: onlyDue,
+ walletBalance,
+ pendingOperations: [],
+ };
yield gatherExchangePending(tx, now, resp, onlyDue);
yield gatherReservePending(tx, now, resp, onlyDue);
yield gatherRefreshPending(tx, now, resp, onlyDue);
@@ -12448,8 +12629,9 @@ function getPendingOperations(ws, onlyDue = false) {
yield gatherProposalPending(tx, now, resp, onlyDue);
yield gatherTipPending(tx, now, resp, onlyDue);
yield gatherPurchasePending(tx, now, resp, onlyDue);
+ yield gatherRecoupPending(tx, now, resp, onlyDue);
+ return resp;
}));
- return resp;
});
}
exports.getPendingOperations = getPendingOperations;
@@ -12459,134 +12641,6 @@ exports.getPendingOperations = getPendingOperations;
unwrapExports(pending);
var pending_1 = pending.getPendingOperations;
-var balance = createCommonjsModule(function (module, exports) {
-/*
- 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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-
-const Amounts = __importStar(amounts);
-
-const logger = new logging.Logger("withdraw.ts");
-/**
- * Get detailed balance information, sliced by exchange and by currency.
- */
-function getBalances(ws) {
- return __awaiter(this, void 0, void 0, function* () {
- logger.trace("starting to compute balance");
- /**
- * Add amount to a balance field, both for
- * the slicing by exchange and currency.
- */
- function addTo(balance, field, amount, exchange) {
- const z = Amounts.getZero(amount.currency);
- const balanceIdentity = {
- available: z,
- paybackAmount: z,
- pendingIncoming: z,
- pendingPayment: z,
- pendingIncomingDirty: z,
- pendingIncomingRefresh: z,
- pendingIncomingWithdraw: z,
- };
- let entryCurr = balance.byCurrency[amount.currency];
- if (!entryCurr) {
- balance.byCurrency[amount.currency] = entryCurr = Object.assign({}, balanceIdentity);
- }
- let entryEx = balance.byExchange[exchange];
- if (!entryEx) {
- balance.byExchange[exchange] = entryEx = Object.assign({}, balanceIdentity);
- }
- entryCurr[field] = Amounts.add(entryCurr[field], amount).amount;
- entryEx[field] = Amounts.add(entryEx[field], amount).amount;
- }
- const balanceStore = {
- byCurrency: {},
- byExchange: {},
- };
- yield ws.db.runWithReadTransaction([dbTypes.Stores.coins, dbTypes.Stores.refreshGroups, dbTypes.Stores.reserves, dbTypes.Stores.purchases, dbTypes.Stores.withdrawalSession], (tx) => __awaiter(this, void 0, void 0, function* () {
- yield tx.iter(dbTypes.Stores.coins).forEach(c => {
- if (c.suspended) {
- return;
- }
- if (c.status === dbTypes.CoinStatus.Fresh) {
- addTo(balanceStore, "available", c.currentAmount, c.exchangeBaseUrl);
- }
- });
- yield tx.iter(dbTypes.Stores.refreshGroups).forEach(r => {
- // Don't count finished refreshes, since the refresh already resulted
- // in coins being added to the wallet.
- if (r.timestampFinished) {
- return;
- }
- for (let i = 0; i < r.oldCoinPubs.length; i++) {
- const session = r.refreshSessionPerCoin[i];
- if (session) {
- addTo(balanceStore, "pendingIncoming", session.amountRefreshOutput, session.exchangeBaseUrl);
- addTo(balanceStore, "pendingIncomingRefresh", session.amountRefreshOutput, session.exchangeBaseUrl);
- }
- }
- });
- yield tx.iter(dbTypes.Stores.withdrawalSession).forEach(wds => {
- let w = wds.totalCoinValue;
- for (let i = 0; i < wds.planchets.length; i++) {
- if (wds.withdrawn[i]) {
- const p = wds.planchets[i];
- if (p) {
- w = Amounts.sub(w, p.coinValue).amount;
- }
- }
- }
- addTo(balanceStore, "pendingIncoming", w, wds.exchangeBaseUrl);
- });
- yield tx.iter(dbTypes.Stores.purchases).forEach(t => {
- if (t.timestampFirstSuccessfulPay) {
- return;
- }
- for (const c of t.payReq.coins) {
- addTo(balanceStore, "pendingPayment", Amounts.parseOrThrow(c.contribution), c.exchange_url);
- }
- });
- }));
- logger.trace("computed balances:", balanceStore);
- return balanceStore;
- });
-}
-exports.getBalances = getBalances;
-
-});
-
-unwrapExports(balance);
-var balance_1 = balance.getBalances;
-
var tip = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
@@ -12603,26 +12657,11 @@ var tip = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+const Amounts = tslib_1.__importStar(amounts);
@@ -12630,7 +12669,7 @@ const Amounts = __importStar(amounts);
function getTipStatus(ws, talerTipUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const res = taleruri.parseTipUri(talerTipUri);
if (!res) {
throw Error("invalid taler://tip URI");
@@ -12646,7 +12685,7 @@ function getTipStatus(ws, talerTipUri) {
console.log("resp:", respJson);
const tipPickupStatus = talerTypes.codecForTipPickupGetResponse().decode(respJson);
console.log("status", tipPickupStatus);
- let amount = Amounts.parseOrThrow(tipPickupStatus.amount);
+ const amount = Amounts.parseOrThrow(tipPickupStatus.amount);
let tipRecord = yield ws.db.get(dbTypes.Stores.tips, [
res.merchantTipId,
res.merchantOrigin,
@@ -12692,8 +12731,8 @@ function getTipStatus(ws, talerTipUri) {
}
exports.getTipStatus = getTipStatus;
function incrementTipRetry(ws, refreshSessionId, err) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.tips], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.tips], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const t = yield tx.get(dbTypes.Stores.tips, refreshSessionId);
if (!t) {
return;
@@ -12710,15 +12749,15 @@ function incrementTipRetry(ws, refreshSessionId, err) {
});
}
function processTip(ws, tipId, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onOpErr = (e) => incrementTipRetry(ws, tipId, e);
yield errors.guardOperationException(() => processTipImpl(ws, tipId, forceNow), onOpErr);
});
}
exports.processTip = processTip;
function resetTipRetry(ws, tipId) {
- return __awaiter(this, void 0, void 0, function* () {
- yield ws.db.mutate(dbTypes.Stores.tips, tipId, x => {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield ws.db.mutate(dbTypes.Stores.tips, tipId, (x) => {
if (x.retryInfo.active) {
x.retryInfo = dbTypes.initRetryInfo();
}
@@ -12727,7 +12766,7 @@ function resetTipRetry(ws, tipId) {
});
}
function processTipImpl(ws, tipId, forceNow) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (forceNow) {
yield resetTipRetry(ws, tipId);
}
@@ -12742,8 +12781,8 @@ function processTipImpl(ws, tipId, forceNow) {
if (!tipRecord.planchets) {
yield exchanges.updateExchangeFromUrl(ws, tipRecord.exchangeUrl);
const denomsForWithdraw = yield withdraw.getVerifiedWithdrawDenomList(ws, tipRecord.exchangeUrl, tipRecord.amount);
- const planchets = yield Promise.all(denomsForWithdraw.map(d => ws.cryptoApi.createTipPlanchet(d)));
- yield ws.db.mutate(dbTypes.Stores.tips, tipId, r => {
+ const planchets = yield Promise.all(denomsForWithdraw.map((d) => ws.cryptoApi.createTipPlanchet(d)));
+ yield ws.db.mutate(dbTypes.Stores.tips, tipId, (r) => {
if (!r.planchets) {
r.planchets = planchets;
}
@@ -12759,7 +12798,7 @@ function processTipImpl(ws, tipId, forceNow) {
}
console.log("got planchets for tip!");
// Planchets in the form that the merchant expects
- const planchetsDetail = tipRecord.planchets.map(p => ({
+ const planchetsDetail = tipRecord.planchets.map((p) => ({
coin_ev: p.coinEv,
denom_pub_hash: p.denomPubHash,
}));
@@ -12784,6 +12823,7 @@ function processTipImpl(ws, tipId, forceNow) {
const planchets = [];
for (let i = 0; i < tipRecord.planchets.length; i++) {
const tipPlanchet = tipRecord.planchets[i];
+ const coinEvHash = yield ws.cryptoApi.hashEncoded(tipPlanchet.coinEv);
const planchet = {
blindingKey: tipPlanchet.blindingKey,
coinEv: tipPlanchet.coinEv,
@@ -12795,29 +12835,30 @@ function processTipImpl(ws, tipId, forceNow) {
reservePub: response.reserve_pub,
withdrawSig: response.reserve_sigs[i].reserve_sig,
isFromTip: true,
+ coinEvHash,
};
planchets.push(planchet);
}
- const withdrawalSessionId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
- const withdrawalSession = {
- denoms: planchets.map(x => x.denomPub),
+ const withdrawalGroupId = talerCrypto.encodeCrock(talerCrypto.getRandomBytes(32));
+ const withdrawalGroup = {
+ denoms: planchets.map((x) => x.denomPub),
exchangeBaseUrl: tipRecord.exchangeUrl,
planchets: planchets,
source: {
- type: "tip",
+ type: "tip" /* Tip */,
tipId: tipRecord.tipId,
},
timestampStart: time.getTimestampNow(),
- withdrawSessionId: withdrawalSessionId,
+ withdrawalGroupId: withdrawalGroupId,
rawWithdrawalAmount: tipRecord.amount,
- withdrawn: planchets.map(x => false),
- totalCoinValue: Amounts.sum(planchets.map(p => p.coinValue)).amount,
+ withdrawn: planchets.map((x) => false),
+ totalCoinValue: Amounts.sum(planchets.map((p) => p.coinValue)).amount,
lastErrorPerCoin: {},
retryInfo: dbTypes.initRetryInfo(),
timestampFinish: undefined,
lastError: undefined,
};
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.tips, dbTypes.Stores.withdrawalSession], (tx) => __awaiter(this, void 0, void 0, function* () {
+ yield ws.db.runWithWriteTransaction([dbTypes.Stores.tips, dbTypes.Stores.withdrawalGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const tr = yield tx.get(dbTypes.Stores.tips, tipId);
if (!tr) {
return;
@@ -12828,14 +12869,14 @@ function processTipImpl(ws, tipId, forceNow) {
tr.pickedUp = true;
tr.retryInfo = dbTypes.initRetryInfo(false);
yield tx.put(dbTypes.Stores.tips, tr);
- yield tx.put(dbTypes.Stores.withdrawalSession, withdrawalSession);
+ yield tx.put(dbTypes.Stores.withdrawalGroups, withdrawalGroup);
}));
- yield withdraw.processWithdrawSession(ws, withdrawalSessionId);
+ yield withdraw.processWithdrawGroup(ws, withdrawalGroupId);
return;
});
}
function acceptTip(ws, tipId) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const tipRecord = yield ws.db.get(dbTypes.Stores.tips, tipId);
if (!tipRecord) {
console.log("tip not found");
@@ -12856,96 +12897,6 @@ var tip_1 = tip.getTipStatus;
var tip_2 = tip.processTip;
var tip_3 = tip.acceptTip;
-var payback_1 = createCommonjsModule(function (module, exports) {
-/*
- 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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-
-
-
-
-const logger = new logging.Logger("payback.ts");
-function payback(ws, coinPub) {
- return __awaiter(this, void 0, void 0, function* () {
- let coin = yield ws.db.get(dbTypes.Stores.coins, coinPub);
- if (!coin) {
- throw Error(`Coin ${coinPub} not found, can't request payback`);
- }
- const reservePub = coin.reservePub;
- if (!reservePub) {
- throw Error(`Can't request payback for a refreshed coin`);
- }
- const reserve = yield ws.db.get(dbTypes.Stores.reserves, reservePub);
- if (!reserve) {
- throw Error(`Reserve of coin ${coinPub} not found`);
- }
- switch (coin.status) {
- case dbTypes.CoinStatus.Dormant:
- throw Error(`Can't do payback for coin ${coinPub} since it's dormant`);
- }
- coin.status = dbTypes.CoinStatus.Dormant;
- // Even if we didn't get the payback yet, we suspend withdrawal, since
- // technically we might update reserve status before we get the response
- // from the reserve for the payback request.
- reserve.hasPayback = true;
- yield ws.db.runWithWriteTransaction([dbTypes.Stores.coins, dbTypes.Stores.reserves], (tx) => __awaiter(this, void 0, void 0, function* () {
- yield tx.put(dbTypes.Stores.coins, coin);
- yield tx.put(dbTypes.Stores.reserves, reserve);
- }));
- ws.notify({
- type: "payback-started" /* PaybackStarted */,
- });
- const paybackRequest = yield ws.cryptoApi.createPaybackRequest(coin);
- const reqUrl = new URL("payback", coin.exchangeBaseUrl);
- const resp = yield ws.http.postJson(reqUrl.href, paybackRequest);
- if (resp.status !== 200) {
- throw Error();
- }
- const paybackConfirmation = talerTypes.codecForRecoupConfirmation().decode(yield resp.json());
- if (paybackConfirmation.reserve_pub !== coin.reservePub) {
- throw Error(`Coin's reserve doesn't match reserve on payback`);
- }
- coin = yield ws.db.get(dbTypes.Stores.coins, coinPub);
- if (!coin) {
- throw Error(`Coin ${coinPub} not found, can't confirm payback`);
- }
- coin.status = dbTypes.CoinStatus.Dormant;
- yield ws.db.put(dbTypes.Stores.coins, coin);
- ws.notify({
- type: "payback-finished" /* PaybackFinished */,
- });
- yield exchanges.updateExchangeFromUrl(ws, coin.exchangeBaseUrl, true);
- });
-}
-exports.payback = payback;
-
-});
-
-unwrapExports(payback_1);
-var payback_2 = payback_1.payback;
-
var wallet = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
@@ -12962,24 +12913,9 @@ var wallet = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
+
+
@@ -13001,6 +12937,7 @@ const withdraw_2 = withdraw;
+
const builtinCurrencies = [
{
auditors: [
@@ -13043,7 +12980,7 @@ class Wallet {
* Execute one operation based on the pending operation info record.
*/
processOnePendingOperation(pending, forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
console.log("running pending", pending);
switch (pending.type) {
case "bug" /* Bug */:
@@ -13059,7 +12996,7 @@ class Wallet {
yield reserves.processReserve(this.ws, pending.reservePub, forceNow);
break;
case "withdraw" /* Withdraw */:
- yield withdraw_2.processWithdrawSession(this.ws, pending.withdrawSessionId, forceNow);
+ yield withdraw_2.processWithdrawGroup(this.ws, pending.withdrawalGroupId, forceNow);
break;
case "proposal-choice" /* ProposalChoice */:
// Nothing to do, user needs to accept/reject
@@ -13082,6 +13019,9 @@ class Wallet {
case "refund-apply" /* RefundApply */:
yield refund.processPurchaseApplyRefund(this.ws, pending.proposalId, forceNow);
break;
+ case "recoup" /* Recoup */:
+ yield recoup.processRecoupGroup(this.ws, pending.recoupGroupId, forceNow);
+ break;
default:
assertUnreachable_1.assertUnreachable(pending);
}
@@ -13091,15 +13031,20 @@ class Wallet {
* Process pending operations.
*/
runPending(forceNow = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const onlyDue = !forceNow;
- const pendingOpsResponse = yield this.getPendingOperations(onlyDue);
+ const pendingOpsResponse = yield this.getPendingOperations({ onlyDue });
for (const p of pendingOpsResponse.pendingOperations) {
try {
yield this.processOnePendingOperation(p, forceNow);
}
catch (e) {
- console.error(e);
+ if (e instanceof errors.OperationFailedAndReportedError) {
+ console.error("Operation failed:", JSON.stringify(e.operationError, undefined, 2));
+ }
+ else {
+ console.error(e);
+ }
}
}
});
@@ -13110,17 +13055,17 @@ class Wallet {
* returns without resolving to an exception.
*/
runUntilDone() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = new Promise((resolve, reject) => {
// Run this asynchronously
- this.addNotificationListener(n => {
+ this.addNotificationListener((n) => {
if (n.type === "waiting-for-retry" /* WaitingForRetry */ &&
n.numGivingLiveness == 0) {
logger.trace("no liveness-giving operations left, returning");
resolve();
}
});
- this.runRetryLoop().catch(e => {
+ this.runRetryLoop().catch((e) => {
console.log("exception in wallet retry loop");
reject(e);
});
@@ -13129,22 +13074,22 @@ class Wallet {
});
}
/**
- * Run the wallet until there are no more pending operations that give
- * liveness left. The wallet will be in a stopped state when this function
- * returns without resolving to an exception.
- */
+ * Run the wallet until there are no more pending operations that give
+ * liveness left. The wallet will be in a stopped state when this function
+ * returns without resolving to an exception.
+ */
runUntilDoneAndStop() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const p = new Promise((resolve, reject) => {
// Run this asynchronously
- this.addNotificationListener(n => {
+ this.addNotificationListener((n) => {
if (n.type === "waiting-for-retry" /* WaitingForRetry */ &&
n.numGivingLiveness == 0) {
logger.trace("no liveness-giving operations left, stopping");
this.stop();
}
});
- this.runRetryLoop().catch(e => {
+ this.runRetryLoop().catch((e) => {
console.log("exception in wallet retry loop");
reject(e);
});
@@ -13157,9 +13102,9 @@ class Wallet {
* a loop until the wallet is stopped explicitly.
*/
runRetryLoop() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
// Make sure we only run one main loop at a time.
- return this.memoRunRetryLoop.memo(() => __awaiter(this, void 0, void 0, function* () {
+ return this.memoRunRetryLoop.memo(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
yield this.runRetryLoopImpl();
}
@@ -13171,13 +13116,13 @@ class Wallet {
});
}
runRetryLoopImpl() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
while (!this.stopped) {
console.log("running wallet retry loop iteration");
- let pending = yield this.getPendingOperations(true);
+ const pending = yield this.getPendingOperations({ onlyDue: true });
console.log("pending ops", JSON.stringify(pending, undefined, 2));
if (pending.pendingOperations.length === 0) {
- const allPending = yield this.getPendingOperations(false);
+ const allPending = yield this.getPendingOperations({ onlyDue: false });
let numPending = 0;
let numGivingLiveness = 0;
for (const p of allPending.pendingOperations) {
@@ -13229,16 +13174,16 @@ class Wallet {
* already been applied.
*/
fillDefaults() {
- return __awaiter(this, void 0, void 0, function* () {
- yield this.db.runWithWriteTransaction([dbTypes.Stores.config, dbTypes.Stores.currencies], (tx) => __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield this.db.runWithWriteTransaction([dbTypes.Stores.config, dbTypes.Stores.currencies], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
let applied = false;
- yield tx.iter(dbTypes.Stores.config).forEach(x => {
+ yield tx.iter(dbTypes.Stores.config).forEach((x) => {
if (x.key == "currencyDefaultsApplied" && x.value == true) {
applied = true;
}
});
if (!applied) {
- for (let c of builtinCurrencies) {
+ for (const c of builtinCurrencies) {
yield tx.put(dbTypes.Stores.currencies, c);
}
}
@@ -13252,7 +13197,7 @@ class Wallet {
* yet send to the merchant.
*/
preparePayForUri(talerPayUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return pay.preparePayForUri(this.ws, talerPayUri);
});
}
@@ -13260,7 +13205,7 @@ class Wallet {
* Add a contract to the wallet and sign coins, and send them.
*/
confirmPay(proposalId, sessionIdOverride) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return yield pay.confirmPay(this.ws, proposalId, sessionIdOverride);
}
@@ -13277,7 +13222,7 @@ class Wallet {
* state DORMANT.
*/
processReserve(reservePub) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return yield reserves.processReserve(this.ws, reservePub);
}
@@ -13293,7 +13238,7 @@ class Wallet {
* audited nor trusted already.
*/
createReserve(req) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return reserves_2.createReserve(this.ws, req);
}
@@ -13312,7 +13257,7 @@ class Wallet {
* an unconfirmed reserve should be hidden.
*/
confirmReserve(req) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return reserves_2.confirmReserve(this.ws, req);
}
@@ -13325,12 +13270,12 @@ class Wallet {
* Check if and how an exchange is trusted and/or audited.
*/
getExchangeTrust(exchangeInfo) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return exchanges.getExchangeTrust(this.ws, exchangeInfo);
});
}
getWithdrawDetailsForUri(talerWithdrawUri, maybeSelectedExchange) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return withdraw.getWithdrawDetailsForUri(this.ws, talerWithdrawUri, maybeSelectedExchange);
});
}
@@ -13340,7 +13285,7 @@ class Wallet {
* exchange entry in then DB.
*/
updateExchangeFromUrl(baseUrl, force = false) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return exchanges.updateExchangeFromUrl(this.ws, baseUrl, force);
}
@@ -13353,14 +13298,14 @@ class Wallet {
* Get detailed balance information, sliced by exchange and by currency.
*/
getBalances() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return this.ws.memoGetBalance.memo(() => balance.getBalances(this.ws));
});
}
refresh(oldCoinPub) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
- const refreshGroupId = yield this.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups], (tx) => __awaiter(this, void 0, void 0, function* () {
+ const refreshGroupId = yield this.db.runWithWriteTransaction([dbTypes.Stores.refreshGroups], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield refresh.createRefreshGroup(tx, [{ coinPub: oldCoinPub }], "manual" /* Manual */);
}));
yield refresh.processRefreshGroup(this.ws, refreshGroupId.refreshGroupId);
@@ -13371,7 +13316,7 @@ class Wallet {
});
}
findExchange(exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield this.db.get(dbTypes.Stores.exchanges, exchangeBaseUrl);
});
}
@@ -13379,22 +13324,22 @@ class Wallet {
* Retrive the full event history for this wallet.
*/
getHistory(historyQuery) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return history.getHistory(this.ws, historyQuery);
});
}
- getPendingOperations(onlyDue = false) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.ws.memoGetPending.memo(() => pending.getPendingOperations(this.ws, onlyDue));
+ getPendingOperations({ onlyDue = false } = {}) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ return this.ws.memoGetPending.memo(() => pending.getPendingOperations(this.ws, { onlyDue }));
});
}
acceptExchangeTermsOfService(exchangeBaseUrl, etag) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return exchanges.acceptExchangeTermsOfService(this.ws, exchangeBaseUrl, etag);
});
}
getDenoms(exchangeUrl) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const denoms = yield this.db
.iterIndex(dbTypes.Stores.denominations.exchangeBaseUrlIndex, exchangeUrl)
.toArray();
@@ -13402,50 +13347,45 @@ class Wallet {
});
}
getExchanges() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield this.db.iter(dbTypes.Stores.exchanges).toArray();
});
}
getCurrencies() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield this.db.iter(dbTypes.Stores.currencies).toArray();
});
}
updateCurrency(currencyRecord) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
logger.trace("updating currency to", currencyRecord);
yield this.db.put(dbTypes.Stores.currencies, currencyRecord);
});
}
getReserves(exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
- return yield this.db
- .iter(dbTypes.Stores.reserves)
- .filter(r => r.exchangeBaseUrl === exchangeBaseUrl);
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ if (exchangeBaseUrl) {
+ return yield this.db
+ .iter(dbTypes.Stores.reserves)
+ .filter((r) => r.exchangeBaseUrl === exchangeBaseUrl);
+ }
+ else {
+ return yield this.db.iter(dbTypes.Stores.reserves).toArray();
+ }
});
}
getCoinsForExchange(exchangeBaseUrl) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield this.db
.iter(dbTypes.Stores.coins)
- .filter(c => c.exchangeBaseUrl === exchangeBaseUrl);
+ .filter((c) => c.exchangeBaseUrl === exchangeBaseUrl);
});
}
getCoins() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield this.db.iter(dbTypes.Stores.coins).toArray();
});
}
- payback(coinPub) {
- return __awaiter(this, void 0, void 0, function* () {
- return payback_1.payback(this.ws, coinPub);
- });
- }
- getPaybackReserves() {
- return __awaiter(this, void 0, void 0, function* () {
- return yield this.db.iter(dbTypes.Stores.reserves).filter(r => r.hasPayback);
- });
- }
/**
* Stop ongoing processing.
*/
@@ -13455,22 +13395,22 @@ class Wallet {
this.ws.cryptoApi.stop();
}
getSenderWireInfos() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const m = {};
- yield this.db.iter(dbTypes.Stores.exchanges).forEach(x => {
+ yield this.db.iter(dbTypes.Stores.exchanges).forEach((x) => {
const wi = x.wireInfo;
if (!wi) {
return;
}
const s = (m[x.baseUrl] = m[x.baseUrl] || new Set());
- Object.keys(wi.feesForType).map(k => s.add(k));
+ Object.keys(wi.feesForType).map((k) => s.add(k));
});
const exchangeWireTypes = {};
- Object.keys(m).map(e => {
+ Object.keys(m).map((e) => {
exchangeWireTypes[e] = Array.from(m[e]);
});
const senderWiresSet = new Set();
- yield this.db.iter(dbTypes.Stores.senderWires).forEach(x => {
+ yield this.db.iter(dbTypes.Stores.senderWires).forEach((x) => {
senderWiresSet.add(x.paytoUri);
});
const senderWires = Array.from(senderWiresSet);
@@ -13484,7 +13424,7 @@ class Wallet {
* Trigger paying coins back into the user's account.
*/
returnCoins(req) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
throw Error("not implemented");
});
}
@@ -13493,22 +13433,22 @@ class Wallet {
* that was involved in the refund.
*/
applyRefund(talerRefundUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return refund.applyRefund(this.ws, talerRefundUri);
});
}
getPurchase(contractTermsHash) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return this.db.get(dbTypes.Stores.purchases, contractTermsHash);
});
}
getFullRefundFees(refundPermissions) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return refund.getFullRefundFees(this.ws, refundPermissions);
});
}
acceptTip(talerTipUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return tip.acceptTip(this.ws, talerTipUri);
}
@@ -13518,12 +13458,12 @@ class Wallet {
});
}
getTipStatus(talerTipUri) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return tip.getTipStatus(this.ws, talerTipUri);
});
}
abortFailedPayment(contractTermsHash) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return pay.abortFailedPayment(this.ws, contractTermsHash);
}
@@ -13537,7 +13477,7 @@ class Wallet {
* confirmation from the bank.).
*/
handleNotifyReserve() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const reserves = yield this.db.iter(dbTypes.Stores.reserves).toArray();
for (const r of reserves) {
if (r.reserveStatus === dbTypes.ReserveRecordStatus.WAIT_CONFIRM_BANK) {
@@ -13556,7 +13496,7 @@ class Wallet {
* based on the current system time.
*/
collectGarbage() {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
// FIXME(#5845)
// We currently do not garbage-collect the wallet database. This might change
// after the feature has been properly re-designed, and we have come up with a
@@ -13564,7 +13504,7 @@ class Wallet {
});
}
acceptWithdrawal(talerWithdrawUri, selectedExchange) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
return reserves.createTalerWithdrawReserve(this.ws, talerWithdrawUri, selectedExchange);
}
@@ -13573,26 +13513,37 @@ class Wallet {
}
});
}
+ updateReserve(reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield reserves.forceQueryReserve(this.ws, reservePub);
+ return yield this.ws.db.get(dbTypes.Stores.reserves, reservePub);
+ });
+ }
+ getReserve(reservePub) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ return yield this.ws.db.get(dbTypes.Stores.reserves, reservePub);
+ });
+ }
refuseProposal(proposalId) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return pay.refuseProposal(this.ws, proposalId);
});
}
getPurchaseDetails(hc) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const purchase = yield this.db.get(dbTypes.Stores.purchases, hc);
if (!purchase) {
throw Error("unknown purchase");
}
- const refundsDoneAmounts = Object.values(purchase.refundState.refundsDone).map(x => Amounts.parseOrThrow(x.perm.refund_amount));
- const refundsPendingAmounts = Object.values(purchase.refundState.refundsPending).map(x => Amounts.parseOrThrow(x.perm.refund_amount));
- const totalRefundAmount = Amounts.sum([
+ const refundsDoneAmounts = Object.values(purchase.refundState.refundsDone).map((x) => amounts.Amounts.parseOrThrow(x.perm.refund_amount));
+ const refundsPendingAmounts = Object.values(purchase.refundState.refundsPending).map((x) => amounts.Amounts.parseOrThrow(x.perm.refund_amount));
+ const totalRefundAmount = amounts.Amounts.sum([
...refundsDoneAmounts,
...refundsPendingAmounts,
]).amount;
- const refundsDoneFees = Object.values(purchase.refundState.refundsDone).map(x => Amounts.parseOrThrow(x.perm.refund_amount));
- const refundsPendingFees = Object.values(purchase.refundState.refundsPending).map(x => Amounts.parseOrThrow(x.perm.refund_amount));
- const totalRefundFees = Amounts.sum([
+ const refundsDoneFees = Object.values(purchase.refundState.refundsDone).map((x) => amounts.Amounts.parseOrThrow(x.perm.refund_amount));
+ const refundsPendingFees = Object.values(purchase.refundState.refundsPending).map((x) => amounts.Amounts.parseOrThrow(x.perm.refund_amount));
+ const totalRefundFees = amounts.Amounts.sum([
...refundsDoneFees,
...refundsPendingFees,
]).amount;
@@ -13608,6 +13559,66 @@ class Wallet {
benchmarkCrypto(repetitions) {
return this.ws.cryptoApi.benchmark(repetitions);
}
+ setCoinSuspended(coinPub, suspended) {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ yield this.db.runWithWriteTransaction([dbTypes.Stores.coins], (tx) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const c = yield tx.get(dbTypes.Stores.coins, coinPub);
+ if (!c) {
+ logger.warn(`coin ${coinPub} not found, won't suspend`);
+ return;
+ }
+ c.suspended = suspended;
+ yield tx.put(dbTypes.Stores.coins, c);
+ }));
+ });
+ }
+ /**
+ * Dump the public information of coins we have in an easy-to-process format.
+ */
+ dumpCoins() {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const coins = yield this.db.iter(dbTypes.Stores.coins).toArray();
+ const coinsJson = { coins: [] };
+ for (const c of coins) {
+ const denom = yield this.db.get(dbTypes.Stores.denominations, [
+ c.exchangeBaseUrl,
+ c.denomPub,
+ ]);
+ if (!denom) {
+ console.error("no denom session found for coin");
+ continue;
+ }
+ const cs = c.coinSource;
+ let refreshParentCoinPub;
+ if (cs.type == "refresh" /* Refresh */) {
+ refreshParentCoinPub = cs.oldCoinPub;
+ }
+ let withdrawalReservePub;
+ if (cs.type == "withdraw" /* Withdraw */) {
+ const ws = yield this.db.get(dbTypes.Stores.withdrawalGroups, cs.withdrawalGroupId);
+ if (!ws) {
+ console.error("no withdrawal session found for coin");
+ continue;
+ }
+ if (ws.source.type == "reserve") {
+ withdrawalReservePub = ws.source.reservePub;
+ }
+ }
+ coinsJson.coins.push({
+ coin_pub: c.coinPub,
+ denom_pub: c.denomPub,
+ denom_pub_hash: c.denomPubHash,
+ denom_value: amounts.Amounts.stringify(denom.value),
+ exchange_base_url: c.exchangeBaseUrl,
+ refresh_parent_coin_pub: refreshParentCoinPub,
+ remaining_value: amounts.Amounts.stringify(c.currentAmount),
+ withdrawal_reserve_pub: withdrawalReservePub,
+ coin_suspended: c.suspended,
+ });
+ }
+ return coinsJson;
+ });
+ }
}
exports.Wallet = Wallet;
@@ -13796,7 +13807,7 @@ unwrapExports(errors$1);
var errors_1$1 = errors$1.AbortError;
var errors_2$1 = errors$1.ConstraintError;
var errors_3$1 = errors$1.DataCloneError;
-var errors_4 = errors$1.DataError;
+var errors_4$1 = errors$1.DataError;
var errors_5 = errors$1.InvalidAccessError;
var errors_6 = errors$1.InvalidStateError;
var errors_7 = errors$1.NotFoundError;
@@ -19843,18 +19854,6 @@ var bind = function bind(fn, thisArg) {
};
};
-/*!
- * Determine if an object is a Buffer
- *
- * @author Feross Aboukhadijeh <https://feross.org>
- * @license MIT
- */
-
-var isBuffer = function isBuffer (obj) {
- return obj != null && obj.constructor != null &&
- typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
-};
-
/*global toString:true*/
// utils is a library of generic helper functions non-specific to axios
@@ -19872,6 +19871,27 @@ function isArray(val) {
}
/**
+ * Determine if a value is undefined
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if the value is undefined, otherwise false
+ */
+function isUndefined(val) {
+ return typeof val === 'undefined';
+}
+
+/**
+ * Determine if a value is a Buffer
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a Buffer, otherwise false
+ */
+function isBuffer(val) {
+ return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
+ && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);
+}
+
+/**
* Determine if a value is an ArrayBuffer
*
* @param {Object} val The value to test
@@ -19928,16 +19948,6 @@ function isNumber(val) {
}
/**
- * Determine if a value is undefined
- *
- * @param {Object} val The value to test
- * @returns {boolean} True if the value is undefined, otherwise false
- */
-function isUndefined(val) {
- return typeof val === 'undefined';
-}
-
-/**
* Determine if a value is an Object
*
* @param {Object} val The value to test
@@ -20411,6 +20421,384 @@ var settle = function settle(resolve, reject, response) {
};
/**
+ * Determines whether the specified URL is absolute
+ *
+ * @param {string} url The URL to test
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
+ */
+var isAbsoluteURL = function isAbsoluteURL(url) {
+ // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
+ // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
+ // by any combination of letters, digits, plus, period, or hyphen.
+ return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
+};
+
+/**
+ * Creates a new URL by combining the specified URLs
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} relativeURL The relative URL
+ * @returns {string} The combined URL
+ */
+var combineURLs = function combineURLs(baseURL, relativeURL) {
+ return relativeURL
+ ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
+ : baseURL;
+};
+
+/**
+ * Creates a new URL by combining the baseURL with the requestedURL,
+ * only when the requestedURL is not already an absolute URL.
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} requestedURL Absolute or relative URL to combine
+ * @returns {string} The combined full path
+ */
+var buildFullPath = function buildFullPath(baseURL, requestedURL) {
+ if (baseURL && !isAbsoluteURL(requestedURL)) {
+ return combineURLs(baseURL, requestedURL);
+ }
+ return requestedURL;
+};
+
+// Headers whose duplicates are ignored by node
+// c.f. https://nodejs.org/api/http.html#http_message_headers
+var ignoreDuplicateOf = [
+ 'age', 'authorization', 'content-length', 'content-type', 'etag',
+ 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
+ 'last-modified', 'location', 'max-forwards', 'proxy-authorization',
+ 'referer', 'retry-after', 'user-agent'
+];
+
+/**
+ * Parse headers into an object
+ *
+ * ```
+ * Date: Wed, 27 Aug 2014 08:58:49 GMT
+ * Content-Type: application/json
+ * Connection: keep-alive
+ * Transfer-Encoding: chunked
+ * ```
+ *
+ * @param {String} headers Headers needing to be parsed
+ * @returns {Object} Headers parsed into an object
+ */
+var parseHeaders = function parseHeaders(headers) {
+ var parsed = {};
+ var key;
+ var val;
+ var i;
+
+ if (!headers) { return parsed; }
+
+ utils.forEach(headers.split('\n'), function parser(line) {
+ i = line.indexOf(':');
+ key = utils.trim(line.substr(0, i)).toLowerCase();
+ val = utils.trim(line.substr(i + 1));
+
+ if (key) {
+ if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
+ return;
+ }
+ if (key === 'set-cookie') {
+ parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
+ } else {
+ parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
+ }
+ }
+ });
+
+ return parsed;
+};
+
+var isURLSameOrigin = (
+ utils.isStandardBrowserEnv() ?
+
+ // Standard browser envs have full support of the APIs needed to test
+ // whether the request URL is of the same origin as current location.
+ (function standardBrowserEnv() {
+ var msie = /(msie|trident)/i.test(navigator.userAgent);
+ var urlParsingNode = document.createElement('a');
+ var originURL;
+
+ /**
+ * Parse a URL to discover it's components
+ *
+ * @param {String} url The URL to be parsed
+ * @returns {Object}
+ */
+ function resolveURL(url) {
+ var href = url;
+
+ if (msie) {
+ // IE needs attribute set twice to normalize properties
+ urlParsingNode.setAttribute('href', href);
+ href = urlParsingNode.href;
+ }
+
+ urlParsingNode.setAttribute('href', href);
+
+ // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
+ return {
+ href: urlParsingNode.href,
+ protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
+ host: urlParsingNode.host,
+ search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
+ hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
+ hostname: urlParsingNode.hostname,
+ port: urlParsingNode.port,
+ pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
+ urlParsingNode.pathname :
+ '/' + urlParsingNode.pathname
+ };
+ }
+
+ originURL = resolveURL(window.location.href);
+
+ /**
+ * Determine if a URL shares the same origin as the current location
+ *
+ * @param {String} requestURL The URL to test
+ * @returns {boolean} True if URL shares the same origin, otherwise false
+ */
+ return function isURLSameOrigin(requestURL) {
+ var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
+ return (parsed.protocol === originURL.protocol &&
+ parsed.host === originURL.host);
+ };
+ })() :
+
+ // Non standard browser envs (web workers, react-native) lack needed support.
+ (function nonStandardBrowserEnv() {
+ return function isURLSameOrigin() {
+ return true;
+ };
+ })()
+);
+
+var cookies = (
+ utils.isStandardBrowserEnv() ?
+
+ // Standard browser envs support document.cookie
+ (function standardBrowserEnv() {
+ return {
+ write: function write(name, value, expires, path, domain, secure) {
+ var cookie = [];
+ cookie.push(name + '=' + encodeURIComponent(value));
+
+ if (utils.isNumber(expires)) {
+ cookie.push('expires=' + new Date(expires).toGMTString());
+ }
+
+ if (utils.isString(path)) {
+ cookie.push('path=' + path);
+ }
+
+ if (utils.isString(domain)) {
+ cookie.push('domain=' + domain);
+ }
+
+ if (secure === true) {
+ cookie.push('secure');
+ }
+
+ document.cookie = cookie.join('; ');
+ },
+
+ read: function read(name) {
+ var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
+ return (match ? decodeURIComponent(match[3]) : null);
+ },
+
+ remove: function remove(name) {
+ this.write(name, '', Date.now() - 86400000);
+ }
+ };
+ })() :
+
+ // Non standard browser env (web workers, react-native) lack needed support.
+ (function nonStandardBrowserEnv() {
+ return {
+ write: function write() {},
+ read: function read() { return null; },
+ remove: function remove() {}
+ };
+ })()
+);
+
+var xhr = function xhrAdapter(config) {
+ return new Promise(function dispatchXhrRequest(resolve, reject) {
+ var requestData = config.data;
+ var requestHeaders = config.headers;
+
+ if (utils.isFormData(requestData)) {
+ delete requestHeaders['Content-Type']; // Let the browser set it
+ }
+
+ var request = new XMLHttpRequest();
+
+ // HTTP basic authentication
+ if (config.auth) {
+ var username = config.auth.username || '';
+ var password = config.auth.password || '';
+ requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
+ }
+
+ var fullPath = buildFullPath(config.baseURL, config.url);
+ request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
+
+ // Set the request timeout in MS
+ request.timeout = config.timeout;
+
+ // Listen for ready state
+ request.onreadystatechange = function handleLoad() {
+ if (!request || request.readyState !== 4) {
+ return;
+ }
+
+ // The request errored out and we didn't get a response, this will be
+ // handled by onerror instead
+ // With one exception: request that using file: protocol, most browsers
+ // will return status as 0 even though it's a successful request
+ if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
+ return;
+ }
+
+ // Prepare the response
+ var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
+ var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
+ var response = {
+ data: responseData,
+ status: request.status,
+ statusText: request.statusText,
+ headers: responseHeaders,
+ config: config,
+ request: request
+ };
+
+ settle(resolve, reject, response);
+
+ // Clean up request
+ request = null;
+ };
+
+ // Handle browser request cancellation (as opposed to a manual cancellation)
+ request.onabort = function handleAbort() {
+ if (!request) {
+ return;
+ }
+
+ reject(createError('Request aborted', config, 'ECONNABORTED', request));
+
+ // Clean up request
+ request = null;
+ };
+
+ // Handle low level network errors
+ request.onerror = function handleError() {
+ // Real errors are hidden from us by the browser
+ // onerror should only fire if it's a network error
+ reject(createError('Network Error', config, null, request));
+
+ // Clean up request
+ request = null;
+ };
+
+ // Handle timeout
+ request.ontimeout = function handleTimeout() {
+ var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
+ if (config.timeoutErrorMessage) {
+ timeoutErrorMessage = config.timeoutErrorMessage;
+ }
+ reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',
+ request));
+
+ // Clean up request
+ request = null;
+ };
+
+ // Add xsrf header
+ // This is only done if running in a standard browser environment.
+ // Specifically not if we're in a web worker, or react-native.
+ if (utils.isStandardBrowserEnv()) {
+ var cookies$1 = cookies;
+
+ // Add xsrf header
+ var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
+ cookies$1.read(config.xsrfCookieName) :
+ undefined;
+
+ if (xsrfValue) {
+ requestHeaders[config.xsrfHeaderName] = xsrfValue;
+ }
+ }
+
+ // Add headers to the request
+ if ('setRequestHeader' in request) {
+ utils.forEach(requestHeaders, function setRequestHeader(val, key) {
+ if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
+ // Remove Content-Type if data is undefined
+ delete requestHeaders[key];
+ } else {
+ // Otherwise add header to the request
+ request.setRequestHeader(key, val);
+ }
+ });
+ }
+
+ // Add withCredentials to request if needed
+ if (!utils.isUndefined(config.withCredentials)) {
+ request.withCredentials = !!config.withCredentials;
+ }
+
+ // Add responseType to request if needed
+ if (config.responseType) {
+ try {
+ request.responseType = config.responseType;
+ } catch (e) {
+ // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
+ // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
+ if (config.responseType !== 'json') {
+ throw e;
+ }
+ }
+ }
+
+ // Handle progress if needed
+ if (typeof config.onDownloadProgress === 'function') {
+ request.addEventListener('progress', config.onDownloadProgress);
+ }
+
+ // Not all browsers support upload events
+ if (typeof config.onUploadProgress === 'function' && request.upload) {
+ request.upload.addEventListener('progress', config.onUploadProgress);
+ }
+
+ if (config.cancelToken) {
+ // Handle cancellation
+ config.cancelToken.promise.then(function onCanceled(cancel) {
+ if (!request) {
+ return;
+ }
+
+ request.abort();
+ reject(cancel);
+ // Clean up request
+ request = null;
+ });
+ }
+
+ if (requestData === undefined) {
+ requestData = null;
+ }
+
+ // Send the request
+ request.send(requestData);
+ });
+};
+
+/**
* Helpers.
*/
@@ -21004,12 +21392,11 @@ var browser_5 = browser.useColors;
var browser_6 = browser.storage;
var browser_7 = browser.colors;
-var hasFlag = (flag, argv) => {
- argv = argv || process.argv;
+var hasFlag = (flag, argv = process.argv) => {
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
- const pos = argv.indexOf(prefix + flag);
- const terminatorPos = argv.indexOf('--');
- return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
+ const position = argv.indexOf(prefix + flag);
+ const terminatorPosition = argv.indexOf('--');
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
};
const {env} = process;
@@ -21026,10 +21413,11 @@ if (hasFlag('no-color') ||
hasFlag('color=always')) {
forceColor = 1;
}
+
if ('FORCE_COLOR' in env) {
- if (env.FORCE_COLOR === true || env.FORCE_COLOR === 'true') {
+ if (env.FORCE_COLOR === 'true') {
forceColor = 1;
- } else if (env.FORCE_COLOR === false || env.FORCE_COLOR === 'false') {
+ } else if (env.FORCE_COLOR === 'false') {
forceColor = 0;
} else {
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
@@ -21049,7 +21437,7 @@ function translateLevel(level) {
};
}
-function supportsColor(stream) {
+function supportsColor(haveStream, streamIsTTY) {
if (forceColor === 0) {
return 0;
}
@@ -21064,7 +21452,7 @@ function supportsColor(stream) {
return 2;
}
- if (stream && !stream.isTTY && forceColor === undefined) {
+ if (haveStream && !streamIsTTY && forceColor === undefined) {
return 0;
}
@@ -21075,15 +21463,10 @@ function supportsColor(stream) {
}
if (process.platform === 'win32') {
- // Node.js 7.5.0 is the first version of Node.js to include a patch to
- // libuv that enables 256 color output on Windows. Anything earlier and it
- // won't work. However, here we target Node.js 8 at minimum as it is an LTS
- // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
- // release that supports 256 colors. Windows 10 build 14931 is the first release
- // that supports 16m/TrueColor.
+ // Windows 10 build 10586 is the first Windows release that supports 256 colors.
+ // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
const osRelease = os.release().split('.');
if (
- Number(process.versions.node.split('.')[0]) >= 8 &&
Number(osRelease[0]) >= 10 &&
Number(osRelease[2]) >= 10586
) {
@@ -21105,6 +21488,10 @@ function supportsColor(stream) {
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
}
+ if ('GITHUB_ACTIONS' in env) {
+ return 1;
+ }
+
if (env.COLORTERM === 'truecolor') {
return 3;
}
@@ -21137,14 +21524,14 @@ function supportsColor(stream) {
}
function getSupportLevel(stream) {
- const level = supportsColor(stream);
+ const level = supportsColor(stream, stream && stream.isTTY);
return translateLevel(level);
}
var supportsColor_1 = {
supportsColor: getSupportLevel,
- stdout: getSupportLevel(process.stdout),
- stderr: getSupportLevel(process.stderr)
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
};
var node = createCommonjsModule(function (module, exports) {
@@ -21678,7 +22065,7 @@ var wrap_1 = wrap;
followRedirects.wrap = wrap_1;
var name = "axios";
-var version = "0.19.0";
+var version = "0.19.2";
var description = "Promise based HTTP client for the browser and node.js";
var main = "index.js";
var scripts = {
@@ -21751,8 +22138,7 @@ var browser$1 = {
};
var typings = "./index.d.ts";
var dependencies = {
- "follow-redirects": "1.5.10",
- "is-buffer": "^2.0.2"
+ "follow-redirects": "1.5.10"
};
var bundlesize = [
{
@@ -21815,13 +22201,10 @@ var isHttps = /https:?/;
/*eslint consistent-return:0*/
var http_1$1 = function httpAdapter(config) {
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
- var timer;
var resolve = function resolve(value) {
- clearTimeout(timer);
resolvePromise(value);
};
var reject = function reject(value) {
- clearTimeout(timer);
rejectPromise(value);
};
var data = config.data;
@@ -21859,7 +22242,8 @@ var http_1$1 = function httpAdapter(config) {
}
// Parse url
- var parsed = url.parse(config.url);
+ var fullPath = buildFullPath(config.baseURL, config.url);
+ var parsed = url.parse(fullPath);
var protocol = parsed.protocol || 'http:';
if (!auth && parsed.auth) {
@@ -21881,6 +22265,7 @@ var http_1$1 = function httpAdapter(config) {
method: config.method.toUpperCase(),
headers: headers,
agent: agent,
+ agents: { http: config.httpAgent, https: config.httpsAgent },
auth: auth
};
@@ -21913,8 +22298,7 @@ var http_1$1 = function httpAdapter(config) {
return true;
}
if (proxyElement[0] === '.' &&
- parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement &&
- proxyElement.match(/\./g).length === parsed.hostname.match(/\./g).length) {
+ parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) {
return true;
}
@@ -22042,10 +22426,15 @@ var http_1$1 = function httpAdapter(config) {
// Handle request timeout
if (config.timeout) {
- timer = setTimeout(function handleRequestTimeout() {
+ // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.
+ // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET.
+ // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.
+ // And then these socket which be hang up will devoring CPU little by little.
+ // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.
+ req.setTimeout(config.timeout, function handleRequestTimeout() {
req.abort();
reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', req));
- }, config.timeout);
+ });
}
if (config.cancelToken) {
@@ -22069,337 +22458,6 @@ var http_1$1 = function httpAdapter(config) {
});
};
-// Headers whose duplicates are ignored by node
-// c.f. https://nodejs.org/api/http.html#http_message_headers
-var ignoreDuplicateOf = [
- 'age', 'authorization', 'content-length', 'content-type', 'etag',
- 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
- 'last-modified', 'location', 'max-forwards', 'proxy-authorization',
- 'referer', 'retry-after', 'user-agent'
-];
-
-/**
- * Parse headers into an object
- *
- * ```
- * Date: Wed, 27 Aug 2014 08:58:49 GMT
- * Content-Type: application/json
- * Connection: keep-alive
- * Transfer-Encoding: chunked
- * ```
- *
- * @param {String} headers Headers needing to be parsed
- * @returns {Object} Headers parsed into an object
- */
-var parseHeaders = function parseHeaders(headers) {
- var parsed = {};
- var key;
- var val;
- var i;
-
- if (!headers) { return parsed; }
-
- utils.forEach(headers.split('\n'), function parser(line) {
- i = line.indexOf(':');
- key = utils.trim(line.substr(0, i)).toLowerCase();
- val = utils.trim(line.substr(i + 1));
-
- if (key) {
- if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
- return;
- }
- if (key === 'set-cookie') {
- parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
- } else {
- parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
- }
- }
- });
-
- return parsed;
-};
-
-var isURLSameOrigin = (
- utils.isStandardBrowserEnv() ?
-
- // Standard browser envs have full support of the APIs needed to test
- // whether the request URL is of the same origin as current location.
- (function standardBrowserEnv() {
- var msie = /(msie|trident)/i.test(navigator.userAgent);
- var urlParsingNode = document.createElement('a');
- var originURL;
-
- /**
- * Parse a URL to discover it's components
- *
- * @param {String} url The URL to be parsed
- * @returns {Object}
- */
- function resolveURL(url) {
- var href = url;
-
- if (msie) {
- // IE needs attribute set twice to normalize properties
- urlParsingNode.setAttribute('href', href);
- href = urlParsingNode.href;
- }
-
- urlParsingNode.setAttribute('href', href);
-
- // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
- return {
- href: urlParsingNode.href,
- protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
- host: urlParsingNode.host,
- search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
- hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
- hostname: urlParsingNode.hostname,
- port: urlParsingNode.port,
- pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
- urlParsingNode.pathname :
- '/' + urlParsingNode.pathname
- };
- }
-
- originURL = resolveURL(window.location.href);
-
- /**
- * Determine if a URL shares the same origin as the current location
- *
- * @param {String} requestURL The URL to test
- * @returns {boolean} True if URL shares the same origin, otherwise false
- */
- return function isURLSameOrigin(requestURL) {
- var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
- return (parsed.protocol === originURL.protocol &&
- parsed.host === originURL.host);
- };
- })() :
-
- // Non standard browser envs (web workers, react-native) lack needed support.
- (function nonStandardBrowserEnv() {
- return function isURLSameOrigin() {
- return true;
- };
- })()
-);
-
-var cookies = (
- utils.isStandardBrowserEnv() ?
-
- // Standard browser envs support document.cookie
- (function standardBrowserEnv() {
- return {
- write: function write(name, value, expires, path, domain, secure) {
- var cookie = [];
- cookie.push(name + '=' + encodeURIComponent(value));
-
- if (utils.isNumber(expires)) {
- cookie.push('expires=' + new Date(expires).toGMTString());
- }
-
- if (utils.isString(path)) {
- cookie.push('path=' + path);
- }
-
- if (utils.isString(domain)) {
- cookie.push('domain=' + domain);
- }
-
- if (secure === true) {
- cookie.push('secure');
- }
-
- document.cookie = cookie.join('; ');
- },
-
- read: function read(name) {
- var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
- return (match ? decodeURIComponent(match[3]) : null);
- },
-
- remove: function remove(name) {
- this.write(name, '', Date.now() - 86400000);
- }
- };
- })() :
-
- // Non standard browser env (web workers, react-native) lack needed support.
- (function nonStandardBrowserEnv() {
- return {
- write: function write() {},
- read: function read() { return null; },
- remove: function remove() {}
- };
- })()
-);
-
-var xhr = function xhrAdapter(config) {
- return new Promise(function dispatchXhrRequest(resolve, reject) {
- var requestData = config.data;
- var requestHeaders = config.headers;
-
- if (utils.isFormData(requestData)) {
- delete requestHeaders['Content-Type']; // Let the browser set it
- }
-
- var request = new XMLHttpRequest();
-
- // HTTP basic authentication
- if (config.auth) {
- var username = config.auth.username || '';
- var password = config.auth.password || '';
- requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
- }
-
- request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);
-
- // Set the request timeout in MS
- request.timeout = config.timeout;
-
- // Listen for ready state
- request.onreadystatechange = function handleLoad() {
- if (!request || request.readyState !== 4) {
- return;
- }
-
- // The request errored out and we didn't get a response, this will be
- // handled by onerror instead
- // With one exception: request that using file: protocol, most browsers
- // will return status as 0 even though it's a successful request
- if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
- return;
- }
-
- // Prepare the response
- var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
- var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
- var response = {
- data: responseData,
- status: request.status,
- statusText: request.statusText,
- headers: responseHeaders,
- config: config,
- request: request
- };
-
- settle(resolve, reject, response);
-
- // Clean up request
- request = null;
- };
-
- // Handle browser request cancellation (as opposed to a manual cancellation)
- request.onabort = function handleAbort() {
- if (!request) {
- return;
- }
-
- reject(createError('Request aborted', config, 'ECONNABORTED', request));
-
- // Clean up request
- request = null;
- };
-
- // Handle low level network errors
- request.onerror = function handleError() {
- // Real errors are hidden from us by the browser
- // onerror should only fire if it's a network error
- reject(createError('Network Error', config, null, request));
-
- // Clean up request
- request = null;
- };
-
- // Handle timeout
- request.ontimeout = function handleTimeout() {
- reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
- request));
-
- // Clean up request
- request = null;
- };
-
- // Add xsrf header
- // This is only done if running in a standard browser environment.
- // Specifically not if we're in a web worker, or react-native.
- if (utils.isStandardBrowserEnv()) {
- var cookies$1 = cookies;
-
- // Add xsrf header
- var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
- cookies$1.read(config.xsrfCookieName) :
- undefined;
-
- if (xsrfValue) {
- requestHeaders[config.xsrfHeaderName] = xsrfValue;
- }
- }
-
- // Add headers to the request
- if ('setRequestHeader' in request) {
- utils.forEach(requestHeaders, function setRequestHeader(val, key) {
- if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
- // Remove Content-Type if data is undefined
- delete requestHeaders[key];
- } else {
- // Otherwise add header to the request
- request.setRequestHeader(key, val);
- }
- });
- }
-
- // Add withCredentials to request if needed
- if (config.withCredentials) {
- request.withCredentials = true;
- }
-
- // Add responseType to request if needed
- if (config.responseType) {
- try {
- request.responseType = config.responseType;
- } catch (e) {
- // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
- // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
- if (config.responseType !== 'json') {
- throw e;
- }
- }
- }
-
- // Handle progress if needed
- if (typeof config.onDownloadProgress === 'function') {
- request.addEventListener('progress', config.onDownloadProgress);
- }
-
- // Not all browsers support upload events
- if (typeof config.onUploadProgress === 'function' && request.upload) {
- request.upload.addEventListener('progress', config.onUploadProgress);
- }
-
- if (config.cancelToken) {
- // Handle cancellation
- config.cancelToken.promise.then(function onCanceled(cancel) {
- if (!request) {
- return;
- }
-
- request.abort();
- reject(cancel);
- // Clean up request
- request = null;
- });
- }
-
- if (requestData === undefined) {
- requestData = null;
- }
-
- // Send the request
- request.send(requestData);
- });
-};
-
var DEFAULT_CONTENT_TYPE = {
'Content-Type': 'application/x-www-form-urlencoded'
};
@@ -22412,13 +22470,12 @@ function setContentTypeIfUnset(headers, value) {
function getDefaultAdapter() {
var adapter;
- // Only Node.JS has a process variable that is of [[Class]] process
- if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
- // For node use HTTP adapter
- adapter = http_1$1;
- } else if (typeof XMLHttpRequest !== 'undefined') {
+ if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = xhr;
+ } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
+ // For node use HTTP adapter
+ adapter = http_1$1;
}
return adapter;
}
@@ -22495,32 +22552,6 @@ utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
var defaults_1 = defaults;
/**
- * Determines whether the specified URL is absolute
- *
- * @param {string} url The URL to test
- * @returns {boolean} True if the specified URL is absolute, otherwise false
- */
-var isAbsoluteURL = function isAbsoluteURL(url) {
- // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
- // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
- // by any combination of letters, digits, plus, period, or hyphen.
- return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
-};
-
-/**
- * Creates a new URL by combining the specified URLs
- *
- * @param {string} baseURL The base URL
- * @param {string} relativeURL The relative URL
- * @returns {string} The combined URL
- */
-var combineURLs = function combineURLs(baseURL, relativeURL) {
- return relativeURL
- ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
- : baseURL;
-};
-
-/**
* Throws a `Cancel` if cancellation has been requested.
*/
function throwIfCancellationRequested(config) {
@@ -22538,11 +22569,6 @@ function throwIfCancellationRequested(config) {
var dispatchRequest = function dispatchRequest(config) {
throwIfCancellationRequested(config);
- // Support baseURL config
- if (config.baseURL && !isAbsoluteURL(config.url)) {
- config.url = combineURLs(config.baseURL, config.url);
- }
-
// Ensure headers exist
config.headers = config.headers || {};
@@ -22557,7 +22583,7 @@ var dispatchRequest = function dispatchRequest(config) {
config.headers = utils.merge(
config.headers.common || {},
config.headers[config.method] || {},
- config.headers || {}
+ config.headers
);
utils.forEach(
@@ -22611,13 +22637,23 @@ var mergeConfig = function mergeConfig(config1, config2) {
config2 = config2 || {};
var config = {};
- utils.forEach(['url', 'method', 'params', 'data'], function valueFromConfig2(prop) {
+ var valueFromConfig2Keys = ['url', 'method', 'params', 'data'];
+ var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy'];
+ var defaultToConfig2Keys = [
+ 'baseURL', 'url', 'transformRequest', 'transformResponse', 'paramsSerializer',
+ 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
+ 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress',
+ 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent',
+ 'httpsAgent', 'cancelToken', 'socketPath'
+ ];
+
+ utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
if (typeof config2[prop] !== 'undefined') {
config[prop] = config2[prop];
}
});
- utils.forEach(['headers', 'auth', 'proxy'], function mergeDeepProperties(prop) {
+ utils.forEach(mergeDeepPropertiesKeys, function mergeDeepProperties(prop) {
if (utils.isObject(config2[prop])) {
config[prop] = utils.deepMerge(config1[prop], config2[prop]);
} else if (typeof config2[prop] !== 'undefined') {
@@ -22629,13 +22665,25 @@ var mergeConfig = function mergeConfig(config1, config2) {
}
});
- utils.forEach([
- 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
- 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
- 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength',
- 'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken',
- 'socketPath'
- ], function defaultToConfig2(prop) {
+ utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
+ if (typeof config2[prop] !== 'undefined') {
+ config[prop] = config2[prop];
+ } else if (typeof config1[prop] !== 'undefined') {
+ config[prop] = config1[prop];
+ }
+ });
+
+ var axiosKeys = valueFromConfig2Keys
+ .concat(mergeDeepPropertiesKeys)
+ .concat(defaultToConfig2Keys);
+
+ var otherKeys = Object
+ .keys(config2)
+ .filter(function filterAxiosKeys(key) {
+ return axiosKeys.indexOf(key) === -1;
+ });
+
+ utils.forEach(otherKeys, function otherKeysDefaultToConfig2(prop) {
if (typeof config2[prop] !== 'undefined') {
config[prop] = config2[prop];
} else if (typeof config1[prop] !== 'undefined') {
@@ -22675,7 +22723,15 @@ Axios.prototype.request = function request(config) {
}
config = mergeConfig(this.defaults, config);
- config.method = config.method ? config.method.toLowerCase() : 'get';
+
+ // Set config.method
+ if (config.method) {
+ config.method = config.method.toLowerCase();
+ } else if (this.defaults.method) {
+ config.method = this.defaults.method.toLowerCase();
+ } else {
+ config.method = 'get';
+ }
// Hook up interceptors middleware
var chain = [dispatchRequest, undefined];
@@ -22888,19 +22944,8 @@ var bank = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Helper functions to deal with the GNU Taler demo bank.
*
@@ -22909,8 +22954,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
/**
* Imports.
*/
-const axios_1 = __importDefault(axios$1);
-
+const axios_1 = tslib_1.__importDefault(axios$1);
+/**
+ * Generate a random alphanumeric ID. Does *not* use cryptographically
+ * secure randomness.
+ */
function makeId(length) {
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -22919,17 +22967,23 @@ function makeId(length) {
}
return result;
}
+/**
+ * Helper function to generate the "Authorization" HTTP header.
+ */
function makeAuth(username, password) {
const auth = `${username}:${password}`;
const authEncoded = Buffer.from(auth).toString("base64");
return `Basic ${authEncoded}`;
}
+/**
+ * Client for the Taler bank access API.
+ */
class Bank {
constructor(bankBaseUrl) {
this.bankBaseUrl = bankBaseUrl;
}
generateWithdrawUri(bankUser, amount) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const body = {
amount,
};
@@ -22940,7 +22994,7 @@ class Bank {
data: body,
responseType: "json",
headers: {
- "Authorization": makeAuth(bankUser.username, bankUser.password),
+ Authorization: makeAuth(bankUser.username, bankUser.password),
},
});
if (resp.status != 200) {
@@ -22954,14 +23008,13 @@ class Bank {
});
}
createReserve(bankUser, amount, reservePub, exchangePaytoUri) {
- return __awaiter(this, void 0, void 0, function* () {
- const reqUrl = new URL("api/withdraw-headless", this.bankBaseUrl).href;
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reqUrl = new URL("testing/withdraw", this.bankBaseUrl).href;
const body = {
- auth: { type: "basic" },
username: bankUser,
amount,
reserve_pub: reservePub,
- exchange_wire_detail: exchangePaytoUri,
+ exchange_payto_uri: exchangePaytoUri,
};
const resp = yield axios_1.default({
method: "post",
@@ -22969,7 +23022,7 @@ class Bank {
data: body,
responseType: "json",
headers: {
- "Authorization": makeAuth(bankUser.username, bankUser.password),
+ Authorization: makeAuth(bankUser.username, bankUser.password),
},
});
if (resp.status != 200) {
@@ -22978,8 +23031,8 @@ class Bank {
});
}
registerRandomUser() {
- return __awaiter(this, void 0, void 0, function* () {
- const reqUrl = new URL("api/register", this.bankBaseUrl).href;
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
+ const reqUrl = new URL("testing/register", this.bankBaseUrl).href;
const randId = makeId(8);
const bankUser = {
username: `testuser-${randId}`,
@@ -22988,7 +23041,7 @@ class Bank {
const resp = yield axios_1.default({
method: "post",
url: reqUrl,
- data: querystring.stringify(bankUser),
+ data: bankUser,
responseType: "json",
});
if (resp.status != 200) {
@@ -23008,7 +23061,7 @@ var bank_1 = bank.Bank;
var cryptoImplementation = createCommonjsModule(function (module, exports) {
/*
This file is part of GNU Taler
- (C) 2019 GNUnet e.V.
+ (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
@@ -23021,16 +23074,10 @@ var cryptoImplementation = createCommonjsModule(function (module, exports) {
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 __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
-const Amounts = __importStar(amounts);
-const timer$1 = __importStar(timer);
+
+
+const timer$1 = tslib_1.__importStar(timer);
@@ -23045,8 +23092,10 @@ var SignaturePurpose;
SignaturePurpose[SignaturePurpose["WALLET_COIN_MELT"] = 1202] = "WALLET_COIN_MELT";
SignaturePurpose[SignaturePurpose["TEST"] = 4242] = "TEST";
SignaturePurpose[SignaturePurpose["MERCHANT_PAYMENT_OK"] = 1104] = "MERCHANT_PAYMENT_OK";
- SignaturePurpose[SignaturePurpose["WALLET_COIN_PAYBACK"] = 1203] = "WALLET_COIN_PAYBACK";
+ SignaturePurpose[SignaturePurpose["WALLET_COIN_RECOUP"] = 1203] = "WALLET_COIN_RECOUP";
SignaturePurpose[SignaturePurpose["WALLET_COIN_LINK"] = 1204] = "WALLET_COIN_LINK";
+ SignaturePurpose[SignaturePurpose["EXCHANGE_CONFIRM_RECOUP"] = 1039] = "EXCHANGE_CONFIRM_RECOUP";
+ SignaturePurpose[SignaturePurpose["EXCHANGE_CONFIRM_RECOUP_REFRESH"] = 1041] = "EXCHANGE_CONFIRM_RECOUP_REFRESH";
})(SignaturePurpose || (SignaturePurpose = {}));
function amountToBuffer(amount) {
const buffer = new ArrayBuffer(8 + 4 + 12);
@@ -23059,10 +23108,11 @@ function amountToBuffer(amount) {
u8buf.set(curr, 8 + 4);
return u8buf;
}
-function timestampToBuffer(ts) {
+function timestampRoundedToBuffer(ts) {
const b = new ArrayBuffer(8);
const v = new DataView(b);
- const s = BigInt(ts.t_ms) * BigInt(1000);
+ const tsRounded = time.timestampTruncateToSecond(ts);
+ const s = BigInt(tsRounded.t_ms) * BigInt(1000);
v.setBigUint64(0, s);
return new Uint8Array(b);
}
@@ -23077,13 +23127,13 @@ class SignaturePurposeBuilder {
}
build() {
let payloadLen = 0;
- for (let c of this.chunks) {
+ 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 (let c of this.chunks) {
+ for (const c of this.chunks) {
u8buf.set(c, p);
p += c.byteLength;
}
@@ -23097,8 +23147,6 @@ function buildSigPS(purposeNum) {
return new SignaturePurposeBuilder(purposeNum);
}
class CryptoImplementation {
- constructor() {
- }
/**
* Create a pre-coin of the given denomination to be withdrawn from then given
* reserve.
@@ -23111,7 +23159,7 @@ class CryptoImplementation {
const blindingFactor = talerCrypto.createBlindingKeySecret();
const coinPubHash = talerCrypto.hash(coinKeyPair.eddsaPub);
const ev = talerCrypto.rsaBlind(coinPubHash, blindingFactor, denomPub);
- const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount;
+ const amountWithFee = amounts.Amounts.add(req.value, req.feeWithdraw).amount;
const denomPubHash = talerCrypto.hash(denomPub);
const evHash = talerCrypto.hash(ev);
const withdrawRequest = buildSigPS(SignaturePurpose.RESERVE_WITHDRAW)
@@ -23132,6 +23180,7 @@ class CryptoImplementation {
denomPubHash: talerCrypto.encodeCrock(denomPubHash),
reservePub: talerCrypto.encodeCrock(reservePub),
withdrawSig: talerCrypto.encodeCrock(sig),
+ coinEvHash: talerCrypto.encodeCrock(evHash),
};
return planchet;
}
@@ -23156,10 +23205,10 @@ class CryptoImplementation {
return tipPlanchet;
}
/**
- * Create and sign a message to request payback for a coin.
+ * Create and sign a message to recoup a coin.
*/
- createPaybackRequest(coin) {
- const p = buildSigPS(SignaturePurpose.WALLET_COIN_PAYBACK)
+ createRecoupRequest(coin) {
+ const p = buildSigPS(SignaturePurpose.WALLET_COIN_RECOUP)
.put(talerCrypto.decodeCrock(coin.coinPub))
.put(talerCrypto.decodeCrock(coin.denomPubHash))
.put(talerCrypto.decodeCrock(coin.blindingKey))
@@ -23170,8 +23219,9 @@ class CryptoImplementation {
coin_blind_key_secret: coin.blindingKey,
coin_pub: coin.coinPub,
coin_sig: talerCrypto.encodeCrock(coinSig),
- denom_pub: coin.denomPub,
+ denom_pub_hash: coin.denomPubHash,
denom_sig: coin.denomSig,
+ refreshed: coin.coinSource.type === "refresh" /* Refresh */,
};
return paybackRequest;
}
@@ -23192,8 +23242,8 @@ class CryptoImplementation {
isValidWireFee(type, wf, masterPub) {
const p = buildSigPS(SignaturePurpose.MASTER_WIRE_FEES)
.put(talerCrypto.hash(talerCrypto.stringToBytes(type + "\0")))
- .put(timestampToBuffer(wf.startStamp))
- .put(timestampToBuffer(wf.endStamp))
+ .put(timestampRoundedToBuffer(wf.startStamp))
+ .put(timestampRoundedToBuffer(wf.endStamp))
.put(amountToBuffer(wf.wireFee))
.put(amountToBuffer(wf.closingFee))
.build();
@@ -23207,10 +23257,10 @@ class CryptoImplementation {
isValidDenom(denom, masterPub) {
const p = buildSigPS(SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY)
.put(talerCrypto.decodeCrock(masterPub))
- .put(timestampToBuffer(denom.stampStart))
- .put(timestampToBuffer(denom.stampExpireWithdraw))
- .put(timestampToBuffer(denom.stampExpireDeposit))
- .put(timestampToBuffer(denom.stampExpireLegal))
+ .put(timestampRoundedToBuffer(denom.stampStart))
+ .put(timestampRoundedToBuffer(denom.stampExpireWithdraw))
+ .put(timestampRoundedToBuffer(denom.stampExpireDeposit))
+ .put(timestampRoundedToBuffer(denom.stampExpireLegal))
.put(amountToBuffer(denom.value))
.put(amountToBuffer(denom.feeWithdraw))
.put(amountToBuffer(denom.feeDeposit))
@@ -23224,9 +23274,7 @@ class CryptoImplementation {
}
isValidWireAccount(paytoUri, sig, masterPub) {
const h = kdf_1.kdf(64, talerCrypto.stringToBytes("exchange-wire-signature"), talerCrypto.stringToBytes(paytoUri + "\0"), new Uint8Array(0));
- const p = buildSigPS(SignaturePurpose.MASTER_WIRE_DETAILS)
- .put(h)
- .build();
+ const p = buildSigPS(SignaturePurpose.MASTER_WIRE_DETAILS).put(h).build();
return talerCrypto.eddsaVerify(p, talerCrypto.decodeCrock(sig), talerCrypto.decodeCrock(masterPub));
}
/**
@@ -23260,8 +23308,8 @@ class CryptoImplementation {
const d = buildSigPS(SignaturePurpose.WALLET_COIN_DEPOSIT)
.put(talerCrypto.decodeCrock(depositInfo.contractTermsHash))
.put(talerCrypto.decodeCrock(depositInfo.wireInfoHash))
- .put(timestampToBuffer(depositInfo.timestamp))
- .put(timestampToBuffer(depositInfo.refundDeadline))
+ .put(timestampRoundedToBuffer(depositInfo.timestamp))
+ .put(timestampRoundedToBuffer(depositInfo.refundDeadline))
.put(amountToBuffer(depositInfo.spendAmount))
.put(amountToBuffer(depositInfo.feeDeposit))
.put(talerCrypto.decodeCrock(depositInfo.merchantPub))
@@ -23271,7 +23319,7 @@ class CryptoImplementation {
const s = {
coin_pub: depositInfo.coinPub,
coin_sig: talerCrypto.encodeCrock(coinSig),
- contribution: Amounts.toString(depositInfo.spendAmount),
+ contribution: amounts.Amounts.stringify(depositInfo.spendAmount),
denom_pub: depositInfo.denomPub,
exchange_url: depositInfo.exchangeBaseUrl,
ub_sig: depositInfo.denomSig,
@@ -23282,13 +23330,13 @@ class CryptoImplementation {
* Create a new refresh session.
*/
createRefreshSession(exchangeBaseUrl, kappa, meltCoin, newCoinDenoms, meltFee) {
- let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency);
+ let valueWithFee = amounts.Amounts.getZero(newCoinDenoms[0].value.currency);
for (const ncd of newCoinDenoms) {
- valueWithFee = Amounts.add(valueWithFee, ncd.value, ncd.feeWithdraw)
+ valueWithFee = amounts.Amounts.add(valueWithFee, ncd.value, ncd.feeWithdraw)
.amount;
}
// melt fee
- valueWithFee = Amounts.add(valueWithFee, meltFee).amount;
+ valueWithFee = amounts.Amounts.add(valueWithFee, meltFee).amount;
const sessionHc = talerCrypto.createHashContext();
const transferPubs = [];
const transferPrivs = [];
@@ -23337,17 +23385,17 @@ class CryptoImplementation {
.put(talerCrypto.decodeCrock(meltCoin.coinPub))
.build();
const confirmSig = talerCrypto.eddsaSign(confirmData, talerCrypto.decodeCrock(meltCoin.coinPriv));
- let valueOutput = Amounts.getZero(newCoinDenoms[0].value.currency);
+ let valueOutput = amounts.Amounts.getZero(newCoinDenoms[0].value.currency);
for (const denom of newCoinDenoms) {
- valueOutput = Amounts.add(valueOutput, denom.value).amount;
+ valueOutput = amounts.Amounts.add(valueOutput, denom.value).amount;
}
const refreshSession = {
confirmSig: talerCrypto.encodeCrock(confirmSig),
exchangeBaseUrl,
hash: talerCrypto.encodeCrock(sessionHash),
meltCoinPub: meltCoin.coinPub,
- newDenomHashes: newCoinDenoms.map(d => d.denomPubHash),
- newDenoms: newCoinDenoms.map(d => d.denomPub),
+ newDenomHashes: newCoinDenoms.map((d) => d.denomPubHash),
+ newDenoms: newCoinDenoms.map((d) => d.denomPub),
norevealIndex: undefined,
planchetsForGammas: planchetsForGammas,
transferPrivs,
@@ -23369,10 +23417,10 @@ class CryptoImplementation {
return talerCrypto.encodeCrock(talerCrypto.hash(b));
}
/**
- * Hash a denomination public key.
+ * Hash a crockford encoded value.
*/
- hashDenomPub(denomPub) {
- return talerCrypto.encodeCrock(talerCrypto.hash(talerCrypto.decodeCrock(denomPub)));
+ hashEncoded(encodedBytes) {
+ return talerCrypto.encodeCrock(talerCrypto.hash(talerCrypto.decodeCrock(encodedBytes)));
}
signCoinLink(oldCoinPriv, newDenomHash, oldCoinPub, transferPub, coinEv) {
const coinEvHash = talerCrypto.hash(talerCrypto.decodeCrock(coinEv));
@@ -23403,7 +23451,7 @@ class CryptoImplementation {
let time_eddsa_create = 0;
for (let i = 0; i < repetitions; i++) {
const start = timer$1.performanceNow();
- const pair = talerCrypto.createEddsaKeyPair();
+ talerCrypto.createEddsaKeyPair();
time_eddsa_create += timer$1.performanceNow() - start;
}
let time_eddsa_sign = 0;
@@ -23442,17 +23490,24 @@ unwrapExports(cryptoImplementation);
var cryptoImplementation_1 = cryptoImplementation.CryptoImplementation;
var nodeThreadWorker = createCommonjsModule(function (module, exports) {
-var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
+/*
+ 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/>
+ */
Object.defineProperty(exports, "__esModule", { value: true });
+const os_1 = tslib_1.__importDefault(os);
const f = __filename;
const workerCode = `
@@ -23501,7 +23556,7 @@ function handleWorkerMessage(msg) {
console.error("RPC operation must be string");
return;
}
- const handleRequest = () => __awaiter(this, void 0, void 0, function* () {
+ const handleRequest = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a;
const impl = new cryptoImplementation.CryptoImplementation();
if (!(operation in impl)) {
@@ -23510,6 +23565,7 @@ function handleWorkerMessage(msg) {
}
try {
const result = impl[operation](...args);
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
const worker_threads$1 = worker_threads;
const p = worker_threads$1.parentPort;
(_a = worker_threads$1.parentPort) === null || _a === void 0 ? void 0 : _a.postMessage;
@@ -23525,7 +23581,7 @@ function handleWorkerMessage(msg) {
return;
}
});
- handleRequest().catch(e => {
+ handleRequest().catch((e) => {
console.error("error in node worker", e);
});
}
@@ -23542,7 +23598,7 @@ class NodeThreadCryptoWorkerFactory {
return new NodeThreadCryptoWorker();
}
getConcurrency() {
- return Math.max(1, os.cpus().length - 1);
+ return Math.max(1, os_1.default.cpus().length - 1);
}
}
exports.NodeThreadCryptoWorkerFactory = NodeThreadCryptoWorkerFactory;
@@ -23551,6 +23607,7 @@ exports.NodeThreadCryptoWorkerFactory = NodeThreadCryptoWorkerFactory;
*/
class NodeThreadCryptoWorker {
constructor() {
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
const worker_threads$1 = worker_threads;
this.nodeWorker = new worker_threads$1.Worker(workerCode, { eval: true });
this.nodeWorker.on("error", (err) => {
@@ -23653,9 +23710,9 @@ class OriginState {
throw Error("assertion failed");
}
const d_s = d.d_ms / 1000;
- this.tokensSecond = Math.min(MAX_PER_SECOND, this.tokensSecond + (d_s / 1000));
- this.tokensMinute = Math.min(MAX_PER_MINUTE, this.tokensMinute + (d_s / 1000 * 60));
- this.tokensHour = Math.min(MAX_PER_HOUR, this.tokensHour + (d_s / 1000 * 60 * 60));
+ this.tokensSecond = Math.min(MAX_PER_SECOND, this.tokensSecond + d_s / 1000);
+ this.tokensMinute = Math.min(MAX_PER_MINUTE, this.tokensMinute + (d_s / 1000) * 60);
+ this.tokensHour = Math.min(MAX_PER_HOUR, this.tokensHour + (d_s / 1000) * 60 * 60);
this.lastUpdate = now;
}
/**
@@ -23701,7 +23758,7 @@ class RequestThrottler {
if (s) {
return s;
}
- const ns = this.perOriginInfo[origin] = new OriginState();
+ const ns = (this.perOriginInfo[origin] = new OriginState());
return ns;
}
/**
@@ -23739,22 +23796,14 @@ var NodeHttpLib_1 = createCommonjsModule(function (module, exports) {
SPDX-License-Identifier: AGPL3.0-or-later
*/
-var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Imports.
+ */
+
-const axios_1 = __importDefault(axios$1);
+const axios_1 = tslib_1.__importDefault(axios$1);
/**
* Implementation of the HTTP request library interface for node.
*/
@@ -23770,31 +23819,24 @@ class NodeHttpLib {
this.throttlingEnabled = enabled;
}
req(method, url, body, opt) {
- var _a;
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.throttlingEnabled && this.throttle.applyThrottle(url)) {
throw Error("request throttled");
}
- let resp;
- try {
- resp = yield axios_1.default({
- method,
- url: url,
- responseType: "text",
- headers: (_a = opt) === null || _a === void 0 ? void 0 : _a.headers,
- validateStatus: () => true,
- transformResponse: (x) => x,
- data: body,
- });
- }
- catch (e) {
- throw e;
- }
+ const resp = yield axios_1.default({
+ method,
+ url: url,
+ responseType: "text",
+ headers: opt === null || opt === void 0 ? void 0 : opt.headers,
+ validateStatus: () => true,
+ transformResponse: (x) => x,
+ data: body,
+ });
const respText = resp.data;
if (typeof respText !== "string") {
throw Error("unexpected response type");
}
- const makeJson = () => __awaiter(this, void 0, void 0, function* () {
+ const makeJson = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let responseJson;
try {
responseJson = JSON.parse(respText);
@@ -23814,18 +23856,18 @@ class NodeHttpLib {
return {
headers,
status: resp.status,
- text: () => __awaiter(this, void 0, void 0, function* () { return resp.data; }),
+ text: () => tslib_1.__awaiter(this, void 0, void 0, function* () { return resp.data; }),
json: makeJson,
};
});
}
get(url, opt) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return this.req("get", url, undefined, opt);
});
}
postJson(url, body, opt) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
return this.req("post", url, body, opt);
});
}
@@ -23853,17 +23895,9 @@ var synchronousWorker = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* The synchronous crypto worker produced by this factory doesn't run in the
* background, but actually blocks the caller until the operation is done.
@@ -23908,7 +23942,7 @@ class SynchronousCryptoWorker {
}
}
handleRequest(operation, id, args) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const impl = new cryptoImplementation.CryptoImplementation();
if (!(operation in impl)) {
console.error(`crypto operation '${operation}' not found`);
@@ -23923,7 +23957,7 @@ class SynchronousCryptoWorker {
return;
}
try {
- setImmediate(() => this.dispatchMessage({ result, id }));
+ setTimeout(() => this.dispatchMessage({ result, id }), 0);
}
catch (e) {
console.log("got error during dispatch", e);
@@ -23949,7 +23983,7 @@ class SynchronousCryptoWorker {
console.error("RPC operation must be string");
return;
}
- this.handleRequest(operation, id, args).catch(e => {
+ this.handleRequest(operation, id, args).catch((e) => {
console.error("Error while handling crypto request:", e);
});
}
@@ -23984,23 +24018,8 @@ var helpers$1 = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
-var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
- result["default"] = mod;
- return result;
-};
Object.defineProperty(exports, "__esModule", { value: true });
+
/**
* Helpers to create headless wallets.
* @author Florian Dold <dold@taler.net>
@@ -24011,9 +24030,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
-const amounts$1 = __importStar(amounts);
-
+const amounts$1 = tslib_1.__importStar(amounts);
+const fs_1 = tslib_1.__importDefault(fs);
@@ -24024,14 +24043,14 @@ const logger = new logging.Logger("helpers.ts");
* Get a wallet instance with default settings for node.
*/
function getDefaultNodeWallet(args = {}) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
build.BridgeIDBFactory.enableTracing = false;
const myBackend = new build.MemoryBackend();
myBackend.enableTracing = false;
const storagePath = args.persistentStoragePath;
if (storagePath) {
try {
- const dbContentStr = fs.readFileSync(storagePath, {
+ const dbContentStr = fs_1.default.readFileSync(storagePath, {
encoding: "utf-8",
});
const dbContent = JSON.parse(dbContentStr);
@@ -24040,13 +24059,13 @@ function getDefaultNodeWallet(args = {}) {
catch (e) {
console.error("could not read wallet file");
}
- myBackend.afterCommitCallback = () => __awaiter(this, void 0, void 0, function* () {
+ myBackend.afterCommitCallback = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
// Allow caller to stop persisting the wallet.
if (args.persistentStoragePath === undefined) {
return;
}
const dbContent = myBackend.exportDump();
- fs.writeFileSync(storagePath, JSON.stringify(dbContent, undefined, 2), {
+ fs_1.default.writeFileSync(storagePath, JSON.stringify(dbContent, undefined, 2), {
encoding: "utf-8",
});
});
@@ -24087,7 +24106,7 @@ function getDefaultNodeWallet(args = {}) {
}
exports.getDefaultNodeWallet = getDefaultNodeWallet;
function withdrawTestBalance(myWallet, amount = "TESTKUDOS:10", bankBaseUrl = "https://bank.test.taler.net/", exchangeBaseUrl = "https://exchange.test.taler.net/") {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
const reserveResponse = yield myWallet.createReserve({
amount: amounts$1.parseOrThrow(amount),
exchange: exchangeBaseUrl,
@@ -24101,9 +24120,13 @@ function withdrawTestBalance(myWallet, amount = "TESTKUDOS:10", bankBaseUrl = "h
"x-taler-bank",
]);
const donePromise = new Promise((resolve, reject) => {
- myWallet.addNotificationListener(n => {
- if (n.type === "reserve-depleted" /* ReserveDepleted */ &&
- n.reservePub === reservePub) {
+ myWallet.runRetryLoop().catch((x) => {
+ reject(x);
+ });
+ myWallet.addNotificationListener((n) => {
+ if (n.type === "withdraw-group-finished" /* WithdrawGroupFinished */ &&
+ n.withdrawalSource.type === "reserve" /* Reserve */ &&
+ n.withdrawalSource.reservePub === reservePub) {
resolve();
}
});
@@ -24137,19 +24160,11 @@ var android = createCommonjsModule(function (module, exports) {
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 __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (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());
- });
-};
Object.defineProperty(exports, "__esModule", { value: true });
+const fs_1 = tslib_1.__importDefault(fs);
// @ts-ignore: special built-in module
@@ -24213,8 +24228,8 @@ class AndroidHttpLib {
const resp = {
headers,
status: msg.status,
- json: () => __awaiter(this, void 0, void 0, function* () { return JSON.parse(msg.responseText); }),
- text: () => __awaiter(this, void 0, void 0, function* () { return msg.responseText; }),
+ json: () => tslib_1.__awaiter(this, void 0, void 0, function* () { return JSON.parse(msg.responseText); }),
+ text: () => tslib_1.__awaiter(this, void 0, void 0, function* () { return msg.responseText; }),
};
p.resolve(resp);
}
@@ -24238,19 +24253,19 @@ class AndroidWalletMessageHandler {
* Handle a request from the Android wallet.
*/
handleMessage(operation, id, args) {
- return __awaiter(this, void 0, void 0, function* () {
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
switch (operation) {
case "init": {
this.walletArgs = {
- notifyHandler: () => __awaiter(this, void 0, void 0, function* () {
- sendAkonoMessage(JSON.stringify({ type: "notification" }));
+ notifyHandler: (notification) => tslib_1.__awaiter(this, void 0, void 0, function* () {
+ sendAkonoMessage(JSON.stringify({ type: "notification", payload: notification }));
}),
persistentStoragePath: args.persistentStoragePath,
httpLib: this.httpLib,
};
const w = yield helpers$1.getDefaultNodeWallet(this.walletArgs);
this.maybeWallet = w;
- w.runRetryLoop().catch(e => {
+ w.runRetryLoop().catch((e) => {
console.error("Error during wallet retry loop", e);
});
this.wp.resolve(w);
@@ -24314,6 +24329,10 @@ class AndroidWalletMessageHandler {
const wallet = yield this.wp.promise;
return yield wallet.getWithdrawDetailsForUri(args.talerWithdrawUri, args.selectedExchange);
}
+ case "applyRefund": {
+ const wallet = yield this.wp.promise;
+ return yield wallet.applyRefund(args.talerRefundUri);
+ }
case "acceptExchangeTermsOfService": {
const wallet = yield this.wp.promise;
return yield wallet.acceptExchangeTermsOfService(args.exchangeBaseUrl, args.etag);
@@ -24327,7 +24346,7 @@ class AndroidWalletMessageHandler {
this.walletArgs = Object.assign({}, oldArgs);
if (oldArgs && oldArgs.persistentStoragePath) {
try {
- fs.unlinkSync(oldArgs.persistentStoragePath);
+ fs_1.default.unlinkSync(oldArgs.persistentStoragePath);
}
catch (e) {
console.error("Error while deleting the wallet db:", e);
@@ -24341,7 +24360,7 @@ class AndroidWalletMessageHandler {
this.maybeWallet = undefined;
const w = yield helpers$1.getDefaultNodeWallet(this.walletArgs);
this.maybeWallet = w;
- w.runRetryLoop().catch(e => {
+ w.runRetryLoop().catch((e) => {
console.error("Error during wallet retry loop", e);
});
this.wp.resolve(w);
@@ -24362,7 +24381,7 @@ function installAndroidWalletListener() {
throw new Error(errMsg);
}
const handler = new AndroidWalletMessageHandler();
- const onMessage = (msgStr) => __awaiter(this, void 0, void 0, function* () {
+ const onMessage = (msgStr) => tslib_1.__awaiter(this, void 0, void 0, function* () {
if (typeof msgStr !== "string") {
console.error("expected string as message");
return;
@@ -24378,7 +24397,13 @@ function installAndroidWalletListener() {
try {
const result = yield handler.handleMessage(operation, id, msg.args);
console.log(`android listener: sending success response for ${operation} (${id})`);
- const respMsg = { type: "response", id, operation, isError: false, result };
+ const respMsg = {
+ type: "response",
+ id,
+ operation,
+ isError: false,
+ result,
+ };
sendMessage(JSON.stringify(respMsg));
}
catch (e) {