make db layer more type safe

This commit is contained in:
Florian Dold 2016-10-18 01:16:31 +02:00
parent 78ea2ba5b1
commit 89c3c2d58d
4 changed files with 117 additions and 83 deletions

View File

@ -34,6 +34,13 @@ declare var cloneInto: any;
namespace TalerNotify { namespace TalerNotify {
const PROTOCOL_VERSION = 1; const PROTOCOL_VERSION = 1;
let logVerbose: boolean = false;
try {
logVerbose = !!localStorage.getItem("taler-log-verbose");
} catch (e) {
// can't read from local storage
}
if (!taler) { if (!taler) {
console.error("Taler wallet lib not included, HTTP 402 payments not" + console.error("Taler wallet lib not included, HTTP 402 payments not" +
" supported"); " supported");
@ -98,7 +105,7 @@ namespace TalerNotify {
function init() { function init() {
chrome.runtime.sendMessage({type: "get-tab-cookie"}, (resp) => { chrome.runtime.sendMessage({type: "get-tab-cookie"}, (resp) => {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
console.log("extension not yet ready"); logVerbose && console.log("extension not yet ready");
window.setTimeout(init, 200); window.setTimeout(init, 200);
return; return;
} }
@ -107,19 +114,19 @@ namespace TalerNotify {
let port = chrome.runtime.connect(); let port = chrome.runtime.connect();
port.onDisconnect.addListener(() => { port.onDisconnect.addListener(() => {
console.log("chrome runtime disconnected, removing handlers"); logVerbose && console.log("chrome runtime disconnected, removing handlers");
for (let handler of handlers) { for (let handler of handlers) {
document.removeEventListener(handler.type, handler.listener); document.removeEventListener(handler.type, handler.listener);
} }
}); });
if (resp && resp.type === "fetch") { if (resp && resp.type === "fetch") {
console.log("it's fetch"); logVerbose && console.log("it's fetch");
taler.internalOfferContractFrom(resp.contractUrl); taler.internalOfferContractFrom(resp.contractUrl);
document.documentElement.style.visibility = "hidden"; document.documentElement.style.visibility = "hidden";
} else if (resp && resp.type === "execute") { } else if (resp && resp.type === "execute") {
console.log("it's execute"); logVerbose && console.log("it's execute");
document.documentElement.style.visibility = "hidden"; document.documentElement.style.visibility = "hidden";
taler.internalExecutePayment(resp.contractHash, taler.internalExecutePayment(resp.contractHash,
resp.payUrl, resp.payUrl,
@ -128,7 +135,7 @@ namespace TalerNotify {
}); });
} }
console.log("loading Taler content script"); logVerbose && console.log("loading Taler content script");
init(); init();
interface HandlerFn { interface HandlerFn {
@ -238,7 +245,7 @@ namespace TalerNotify {
} }
if (resp.isRepurchase) { if (resp.isRepurchase) {
console.log("doing repurchase"); logVerbose && console.log("doing repurchase");
console.assert(resp.existingFulfillmentUrl); console.assert(resp.existingFulfillmentUrl);
console.assert(resp.existingContractHash); console.assert(resp.existingContractHash);
window.location.href = subst(resp.existingFulfillmentUrl, window.location.href = subst(resp.existingFulfillmentUrl,
@ -296,7 +303,7 @@ namespace TalerNotify {
console.error("H_contract missing in taler-payment-succeeded"); console.error("H_contract missing in taler-payment-succeeded");
return; return;
} }
console.log("got taler-payment-succeeded"); logVerbose && console.log("got taler-payment-succeeded");
const walletMsg = { const walletMsg = {
type: "payment-succeeded", type: "payment-succeeded",
detail: { detail: {

View File

@ -15,6 +15,7 @@
*/ */
"use strict"; "use strict";
import {IExchangeInfo} from "./types";
/** /**
* Declarations and helpers for * Declarations and helpers for
@ -27,6 +28,7 @@
const DB_NAME = "taler"; const DB_NAME = "taler";
const DB_VERSION = 10; const DB_VERSION = 10;
/** /**
* Return a promise that resolves * Return a promise that resolves
* to the taler wallet db. * to the taler wallet db.

View File

@ -24,6 +24,16 @@
"use strict"; "use strict";
export class Store<T> {
name: string;
validator?: (v: T) => T;
constructor(name: string, validator?: (v: T) => T) {
this.name = name;
this.validator = validator;
}
}
/** /**
* Stream that can be filtered, reduced or joined * Stream that can be filtered, reduced or joined
* with indices. * with indices.
@ -277,10 +287,10 @@ export class QueryRoot {
this.db = db; this.db = db;
} }
iter<T>(storeName: string, iter<T>(store: Store<T>,
{only = <string | undefined>undefined, indexName = <string | undefined>undefined} = {}): QueryStream<T> { {only = <string | undefined>undefined, indexName = <string | undefined>undefined} = {}): QueryStream<T> {
this.stores.add(storeName); this.stores.add(store.name);
return new IterQueryStream(this, storeName, { only, indexName }); return new IterQueryStream(this, store.name, { only, indexName });
} }
/** /**
@ -288,11 +298,11 @@ export class QueryRoot {
* Overrides if an existing object with the same key exists * Overrides if an existing object with the same key exists
* in the store. * in the store.
*/ */
put(storeName: string, val: any): QueryRoot { put<T>(store: Store<T>, val: T): QueryRoot {
let doPut = (tx: IDBTransaction) => { let doPut = (tx: IDBTransaction) => {
tx.objectStore(storeName).put(val); tx.objectStore(store.name).put(val);
}; };
this.addWork(doPut, storeName, true); this.addWork(doPut, store.name, true);
return this; return this;
} }
@ -302,13 +312,13 @@ export class QueryRoot {
* Fails if the object's key is already present * Fails if the object's key is already present
* in the object store. * in the object store.
*/ */
putAll(storeName: string, iterable: any[]): QueryRoot { putAll<T>(store: Store<T>, iterable: T[]): QueryRoot {
const doPutAll = (tx: IDBTransaction) => { const doPutAll = (tx: IDBTransaction) => {
for (let obj of iterable) { for (let obj of iterable) {
tx.objectStore(storeName).put(obj); tx.objectStore(store.name).put(obj);
} }
}; };
this.addWork(doPutAll, storeName, true); this.addWork(doPutAll, store.name, true);
return this; return this;
} }
@ -317,18 +327,18 @@ export class QueryRoot {
* Fails if the object's key is already present * Fails if the object's key is already present
* in the object store. * in the object store.
*/ */
add(storeName: string, val: any): QueryRoot { add<T>(store: Store<T>, val: T): QueryRoot {
const doAdd = (tx: IDBTransaction) => { const doAdd = (tx: IDBTransaction) => {
tx.objectStore(storeName).add(val); tx.objectStore(store.name).add(val);
}; };
this.addWork(doAdd, storeName, true); this.addWork(doAdd, store.name, true);
return this; return this;
} }
/** /**
* Get one object from a store by its key. * Get one object from a store by its key.
*/ */
get<T>(storeName: any, key: any): Promise<T|undefined> { get<T>(store: Store<T>, key: any): Promise<T|undefined> {
if (key === void 0) { if (key === void 0) {
throw Error("key must not be undefined"); throw Error("key must not be undefined");
} }
@ -336,13 +346,13 @@ export class QueryRoot {
const {resolve, promise} = openPromise(); const {resolve, promise} = openPromise();
const doGet = (tx: IDBTransaction) => { const doGet = (tx: IDBTransaction) => {
const req = tx.objectStore(storeName).get(key); const req = tx.objectStore(store.name).get(key);
req.onsuccess = () => { req.onsuccess = () => {
resolve(req.result); resolve(req.result);
}; };
}; };
this.addWork(doGet, storeName, false); this.addWork(doGet, store.name, false);
return Promise.resolve() return Promise.resolve()
.then(() => this.finish()) .then(() => this.finish())
.then(() => promise); .then(() => promise);

View File

@ -30,7 +30,7 @@ import {
WireInfo, RefreshSession, ReserveRecord, CoinPaySig WireInfo, RefreshSession, ReserveRecord, CoinPaySig
} from "./types"; } from "./types";
import {HttpResponse, RequestException} from "./http"; import {HttpResponse, RequestException} from "./http";
import {QueryRoot} from "./query"; import {QueryRoot, Store} from "./query";
import {Checkable} from "./checkable"; import {Checkable} from "./checkable";
import {canonicalizeBaseUrl} from "./helpers"; import {canonicalizeBaseUrl} from "./helpers";
import {ReserveCreationInfo, Amounts} from "./types"; import {ReserveCreationInfo, Amounts} from "./types";
@ -305,6 +305,17 @@ function getWithdrawDenomList(amountAvailable: AmountJson,
} }
namespace Stores {
export let exchanges: Store<IExchangeInfo> = new Store<IExchangeInfo>("exchanges");
export let transactions: Store<Transaction> = new Store<Transaction>("transactions");
export let reserves: Store<ReserveRecord> = new Store<ReserveRecord>("reserves");
export let coins: Store<Coin> = new Store<Coin>("coins");
export let refresh: Store<RefreshSession> = new Store<RefreshSession>("refresh");
export let history: Store<HistoryRecord> = new Store<HistoryRecord>("history");
export let precoins: Store<PreCoin> = new Store<PreCoin>("precoins");
}
export class Wallet { export class Wallet {
private db: IDBDatabase; private db: IDBDatabase;
private http: HttpRequestLibrary; private http: HttpRequestLibrary;
@ -351,7 +362,7 @@ export class Wallet {
console.log("updating exchanges"); console.log("updating exchanges");
this.q() this.q()
.iter("exchanges") .iter(Stores.exchanges)
.reduce((exchange: IExchangeInfo) => { .reduce((exchange: IExchangeInfo) => {
this.updateExchangeFromUrl(exchange.baseUrl) this.updateExchangeFromUrl(exchange.baseUrl)
.catch((e) => { .catch((e) => {
@ -368,28 +379,28 @@ export class Wallet {
console.log("resuming pending operations from db"); console.log("resuming pending operations from db");
this.q() this.q()
.iter("reserves") .iter(Stores.reserves)
.reduce((reserve: any) => { .reduce((reserve) => {
console.log("resuming reserve", reserve.reserve_pub); console.log("resuming reserve", reserve.reserve_pub);
this.processReserve(reserve); this.processReserve(reserve);
}); });
this.q() this.q()
.iter("precoins") .iter(Stores.precoins)
.reduce((preCoin: any) => { .reduce((preCoin) => {
console.log("resuming precoin"); console.log("resuming precoin");
this.processPreCoin(preCoin); this.processPreCoin(preCoin);
}); });
this.q() this.q()
.iter("refresh") .iter(Stores.refresh)
.reduce((r: RefreshSession) => { .reduce((r: RefreshSession) => {
this.continueRefreshSession(r); this.continueRefreshSession(r);
}); });
// FIXME: optimize via index // FIXME: optimize via index
this.q() this.q()
.iter("coins") .iter(Stores.coins)
.reduce((c: Coin) => { .reduce((c: Coin) => {
if (c.dirty && !c.transactionPending) { if (c.dirty && !c.transactionPending) {
this.refresh(c.coinPub); this.refresh(c.coinPub);
@ -452,7 +463,7 @@ export class Wallet {
console.log("Checking for merchant's exchange", JSON.stringify(info)); console.log("Checking for merchant's exchange", JSON.stringify(info));
return [ return [
this.q() this.q()
.iter("exchanges", {indexName: "pubKey", only: info.master_pub}) .iter(Stores.exchanges, {indexName: "pubKey", only: info.master_pub})
.indexJoin("coins", .indexJoin("coins",
"exchangeBaseUrl", "exchangeBaseUrl",
(exchange) => exchange.baseUrl) (exchange) => exchange.baseUrl)
@ -536,7 +547,7 @@ export class Wallet {
merchantSig: offer.merchant_sig, merchantSig: offer.merchant_sig,
}; };
let historyEntry = { let historyEntry: HistoryRecord = {
type: "pay", type: "pay",
timestamp: (new Date).getTime(), timestamp: (new Date).getTime(),
subjectId: `contract-${offer.H_contract}`, subjectId: `contract-${offer.H_contract}`,
@ -545,13 +556,14 @@ export class Wallet {
amount: offer.contract.amount, amount: offer.contract.amount,
contractHash: offer.H_contract, contractHash: offer.H_contract,
fulfillmentUrl: offer.contract.fulfillment_url, fulfillmentUrl: offer.contract.fulfillment_url,
} },
level: HistoryLevel.User
}; };
await this.q() await this.q()
.put("transactions", t) .put(Stores.transactions, t)
.put("history", historyEntry) .put(Stores.history, historyEntry)
.putAll("coins", payCoinInfo.map((pci) => pci.updatedCoin)) .putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
.finish(); .finish();
this.notifier.notify(); this.notifier.notify();
@ -559,7 +571,7 @@ export class Wallet {
async putHistory(historyEntry: HistoryRecord): Promise<void> { async putHistory(historyEntry: HistoryRecord): Promise<void> {
await this.q().put("history", historyEntry).finish(); await this.q().put(Stores.history, historyEntry).finish();
this.notifier.notify(); this.notifier.notify();
} }
@ -571,7 +583,7 @@ export class Wallet {
async confirmPay(offer: Offer): Promise<any> { async confirmPay(offer: Offer): Promise<any> {
console.log("executing confirmPay"); console.log("executing confirmPay");
let transaction = await this.q().get("transactions", offer.H_contract); let transaction = await this.q().get(Stores.transactions, offer.H_contract);
if (transaction) { if (transaction) {
// Already payed ... // Already payed ...
@ -604,7 +616,7 @@ export class Wallet {
*/ */
async checkPay(offer: Offer): Promise<any> { async checkPay(offer: Offer): Promise<any> {
// First check if we already payed for it. // First check if we already payed for it.
let transaction = await this.q().get("transactions", offer.H_contract); let transaction = await this.q().get(Stores.transactions, offer.H_contract);
if (transaction) { if (transaction) {
return {isPayed: true}; return {isPayed: true};
} }
@ -629,7 +641,7 @@ export class Wallet {
* with the given hash. * with the given hash.
*/ */
async executePayment(H_contract: string): Promise<any> { async executePayment(H_contract: string): Promise<any> {
let t = await this.q().get<Transaction>("transactions", H_contract); let t = await this.q().get<Transaction>(Stores.transactions, H_contract);
if (!t) { if (!t) {
return { return {
success: false, success: false,
@ -661,7 +673,7 @@ export class Wallet {
let n = await this.depleteReserve(reserve, exchange); let n = await this.depleteReserve(reserve, exchange);
if (n != 0) { if (n != 0) {
let depleted = { let depleted: HistoryRecord = {
type: "depleted-reserve", type: "depleted-reserve",
subjectId: `reserve-progress-${reserveRecord.reserve_pub}`, subjectId: `reserve-progress-${reserveRecord.reserve_pub}`,
timestamp: (new Date).getTime(), timestamp: (new Date).getTime(),
@ -670,9 +682,10 @@ export class Wallet {
reservePub: reserveRecord.reserve_pub, reservePub: reserveRecord.reserve_pub,
requestedAmount: reserveRecord.requested_amount, requestedAmount: reserveRecord.requested_amount,
currentAmount: reserveRecord.current_amount, currentAmount: reserveRecord.current_amount,
} },
level: HistoryLevel.User
}; };
await this.q().put("history", depleted).finish(); await this.q().put(Stores.history, depleted).finish();
} }
} catch (e) { } catch (e) {
// random, exponential backoff truncated at 3 minutes // random, exponential backoff truncated at 3 minutes
@ -736,8 +749,8 @@ export class Wallet {
}; };
await this.q() await this.q()
.put("reserves", reserveRecord) .put(Stores.reserves, reserveRecord)
.put("history", historyEntry) .put(Stores.history, historyEntry)
.finish(); .finish();
let r: CreateReserveResponse = { let r: CreateReserveResponse = {
@ -760,14 +773,14 @@ export class Wallet {
async confirmReserve(req: ConfirmReserveRequest): Promise<void> { async confirmReserve(req: ConfirmReserveRequest): Promise<void> {
const now = (new Date).getTime(); const now = (new Date).getTime();
let reserve: ReserveRecord|undefined = await ( let reserve: ReserveRecord|undefined = await (
this.q().get<ReserveRecord>("reserves", this.q().get<ReserveRecord>(Stores.reserves,
req.reservePub)); req.reservePub));
if (!reserve) { if (!reserve) {
console.error("Unable to confirm reserve, not found in DB"); console.error("Unable to confirm reserve, not found in DB");
return; return;
} }
console.log("reserve confirmed"); console.log("reserve confirmed");
const historyEntry = { const historyEntry: HistoryRecord = {
type: "confirm-reserve", type: "confirm-reserve",
timestamp: now, timestamp: now,
subjectId: `reserve-progress-${reserve.reserve_pub}`, subjectId: `reserve-progress-${reserve.reserve_pub}`,
@ -775,12 +788,13 @@ export class Wallet {
exchangeBaseUrl: reserve.exchange_base_url, exchangeBaseUrl: reserve.exchange_base_url,
reservePub: req.reservePub, reservePub: req.reservePub,
requestedAmount: reserve.requested_amount, requestedAmount: reserve.requested_amount,
} },
level: HistoryLevel.User,
}; };
reserve.confirmed = true; reserve.confirmed = true;
await this.q() await this.q()
.put("reserves", reserve) .put(Stores.reserves, reserve)
.put("history", historyEntry) .put(Stores.history, historyEntry)
.finish(); .finish();
this.processReserve(reserve); this.processReserve(reserve);
@ -788,7 +802,8 @@ export class Wallet {
private async withdrawExecute(pc: PreCoin): Promise<Coin> { private async withdrawExecute(pc: PreCoin): Promise<Coin> {
let reserve = await this.q().get<ReserveRecord>("reserves", pc.reservePub); let reserve = await this.q().get<ReserveRecord>(Stores.reserves,
pc.reservePub);
if (!reserve) { if (!reserve) {
throw Error("db inconsistent"); throw Error("db inconsistent");
@ -837,8 +852,8 @@ export class Wallet {
}; };
await this.q() await this.q()
.delete("precoins", coin.coinPub) .delete("precoins", coin.coinPub)
.add("coins", coin) .add(Stores.coins, coin)
.add("history", historyEntry) .add(Stores.history, historyEntry)
.finish(); .finish();
this.notifier.notify(); this.notifier.notify();
} }
@ -853,7 +868,7 @@ export class Wallet {
let preCoin = await this.cryptoApi let preCoin = await this.cryptoApi
.createPreCoin(denom, reserve); .createPreCoin(denom, reserve);
await this.q() await this.q()
.put("precoins", preCoin) .put(Stores.precoins, preCoin)
.finish(); .finish();
await this.processPreCoin(preCoin); await this.processPreCoin(preCoin);
} }
@ -881,7 +896,7 @@ export class Wallet {
private async updateReserve(reservePub: string, private async updateReserve(reservePub: string,
exchange: IExchangeInfo): Promise<ReserveRecord> { exchange: IExchangeInfo): Promise<ReserveRecord> {
let reserve = await this.q() let reserve = await this.q()
.get<ReserveRecord>("reserves", reservePub); .get<ReserveRecord>(Stores.reserves, reservePub);
if (!reserve) { if (!reserve) {
throw Error("reserve not in db"); throw Error("reserve not in db");
} }
@ -910,7 +925,7 @@ export class Wallet {
} }
}; };
await this.q() await this.q()
.put("reserves", reserve) .put(Stores.reserves, reserve)
.finish(); .finish();
return reserve; return reserve;
} }
@ -982,7 +997,7 @@ export class Wallet {
private async suspendCoins(exchangeInfo: IExchangeInfo): Promise<void> { private async suspendCoins(exchangeInfo: IExchangeInfo): Promise<void> {
let suspendedCoins = await ( let suspendedCoins = await (
this.q() this.q()
.iter("coins", .iter(Stores.coins,
{indexName: "exchangeBaseUrl", only: exchangeInfo.baseUrl}) {indexName: "exchangeBaseUrl", only: exchangeInfo.baseUrl})
.reduce((coin: Coin, suspendedCoins: Coin[]) => { .reduce((coin: Coin, suspendedCoins: Coin[]) => {
if (!exchangeInfo.active_denoms.find((c) => c.denom_pub == coin.denomPub)) { if (!exchangeInfo.active_denoms.find((c) => c.denom_pub == coin.denomPub)) {
@ -995,7 +1010,7 @@ export class Wallet {
suspendedCoins.map((c) => { suspendedCoins.map((c) => {
console.log("suspending coin", c); console.log("suspending coin", c);
c.suspended = true; c.suspended = true;
q.put("coins", c); q.put(Stores.coins, c);
}); });
await q.finish(); await q.finish();
} }
@ -1008,7 +1023,7 @@ export class Wallet {
throw Error("invalid update time"); throw Error("invalid update time");
} }
let r = await this.q().get<IExchangeInfo>("exchanges", baseUrl); let r = await this.q().get<IExchangeInfo>(Stores.exchanges, baseUrl);
let exchangeInfo: IExchangeInfo; let exchangeInfo: IExchangeInfo;
@ -1035,7 +1050,7 @@ export class Wallet {
await this.suspendCoins(updatedExchangeInfo); await this.suspendCoins(updatedExchangeInfo);
await this.q() await this.q()
.put("exchanges", updatedExchangeInfo) .put(Stores.exchanges, updatedExchangeInfo)
.finish(); .finish();
return updatedExchangeInfo; return updatedExchangeInfo;
@ -1120,7 +1135,7 @@ export class Wallet {
let byCurrency = await ( let byCurrency = await (
this.q() this.q()
.iter("coins") .iter(Stores.coins)
.reduce(collectBalances, {})); .reduce(collectBalances, {}));
return {balances: byCurrency}; return {balances: byCurrency};
@ -1131,13 +1146,13 @@ export class Wallet {
// FIXME: this is not running in a transaction. // FIXME: this is not running in a transaction.
let coin = await this.q().get<Coin>("coins", oldCoinPub); let coin = await this.q().get<Coin>(Stores.coins, oldCoinPub);
if (!coin) { if (!coin) {
throw Error("coin not found"); throw Error("coin not found");
} }
let exchange = await this.q().get<IExchangeInfo>("exchanges", let exchange = await this.q().get<IExchangeInfo>(Stores.exchanges,
coin.exchangeBaseUrl); coin.exchangeBaseUrl);
if (!exchange) { if (!exchange) {
throw Error("db inconsistent"); throw Error("db inconsistent");
@ -1177,8 +1192,8 @@ export class Wallet {
// FIXME: we should check whether the amount still matches! // FIXME: we should check whether the amount still matches!
await this.q() await this.q()
.put("refresh", refreshSession) .put(Stores.refresh, refreshSession)
.put("coins", coin) .put(Stores.coins, coin)
.finish(); .finish();
return refreshSession; return refreshSession;
@ -1187,11 +1202,11 @@ export class Wallet {
async refresh(oldCoinPub: string): Promise<void> { async refresh(oldCoinPub: string): Promise<void> {
let refreshSession: RefreshSession|undefined; let refreshSession: RefreshSession|undefined;
let oldSession = await this.q().get<RefreshSession>("refresh", oldCoinPub); let oldSession = await this.q().get(Stores.refresh, oldCoinPub);
if (oldSession) { if (oldSession) {
refreshSession = oldSession; refreshSession = oldSession;
} else { } else {
refreshSession = await this.q().get<RefreshSession>("refresh", refreshSession = await this.q().get(Stores.refresh,
oldCoinPub); oldCoinPub);
} }
if (!refreshSession) { if (!refreshSession) {
@ -1208,7 +1223,7 @@ export class Wallet {
if (typeof refreshSession.norevealIndex !== "number") { if (typeof refreshSession.norevealIndex !== "number") {
let coinPub = refreshSession.meltCoinPub; let coinPub = refreshSession.meltCoinPub;
await this.refreshMelt(refreshSession); await this.refreshMelt(refreshSession);
let r = await this.q().get<RefreshSession>("refresh", coinPub); let r = await this.q().get<RefreshSession>(Stores.refresh, coinPub);
if (!r) { if (!r) {
throw Error("refresh session does not exist anymore"); throw Error("refresh session does not exist anymore");
} }
@ -1225,7 +1240,7 @@ export class Wallet {
return; return;
} }
let coin = await this.q().get<Coin>("coins", refreshSession.meltCoinPub); let coin = await this.q().get<Coin>(Stores.coins, refreshSession.meltCoinPub);
if (!coin) { if (!coin) {
console.error("can't melt coin, it does not exist"); console.error("can't melt coin, it does not exist");
return; return;
@ -1271,7 +1286,7 @@ export class Wallet {
refreshSession.norevealIndex = norevealIndex; refreshSession.norevealIndex = norevealIndex;
await this.q().put("refresh", refreshSession).finish(); await this.q().put(Stores.refresh, refreshSession).finish();
} }
@ -1307,7 +1322,7 @@ export class Wallet {
console.log("/refresh/reveal did not contain ev_sigs"); console.log("/refresh/reveal did not contain ev_sigs");
} }
let exchange = await this.q().get<IExchangeInfo>("exchanges", let exchange = await this.q().get<IExchangeInfo>(Stores.exchanges,
refreshSession.exchangeBaseUrl); refreshSession.exchangeBaseUrl);
if (!exchange) { if (!exchange) {
console.error(`exchange ${refreshSession.exchangeBaseUrl} not found`); console.error(`exchange ${refreshSession.exchangeBaseUrl} not found`);
@ -1343,8 +1358,8 @@ export class Wallet {
refreshSession.finished = true; refreshSession.finished = true;
await this.q() await this.q()
.putAll("coins", coins) .putAll(Stores.coins, coins)
.put("refresh", refreshSession) .put(Stores.refresh, refreshSession)
.finish(); .finish();
} }
@ -1360,7 +1375,7 @@ export class Wallet {
let history = await ( let history = await (
this.q() this.q()
.iter("history", {indexName: "timestamp"}) .iter(Stores.history, {indexName: "timestamp"})
.reduce(collect, [])); .reduce(collect, []));
return {history}; return {history};
@ -1368,28 +1383,28 @@ export class Wallet {
async getExchanges(): Promise<IExchangeInfo[]> { async getExchanges(): Promise<IExchangeInfo[]> {
return this.q() return this.q()
.iter<IExchangeInfo>("exchanges") .iter<IExchangeInfo>(Stores.exchanges)
.flatMap((e) => [e]) .flatMap((e) => [e])
.toArray(); .toArray();
} }
async getReserves(exchangeBaseUrl: string): Promise<ReserveRecord[]> { async getReserves(exchangeBaseUrl: string): Promise<ReserveRecord[]> {
return this.q() return this.q()
.iter<ReserveRecord>("reserves") .iter<ReserveRecord>(Stores.reserves)
.filter((r: ReserveRecord) => r.exchange_base_url === exchangeBaseUrl) .filter((r: ReserveRecord) => r.exchange_base_url === exchangeBaseUrl)
.toArray(); .toArray();
} }
async getCoins(exchangeBaseUrl: string): Promise<Coin[]> { async getCoins(exchangeBaseUrl: string): Promise<Coin[]> {
return this.q() return this.q()
.iter<Coin>("coins") .iter<Coin>(Stores.coins)
.filter((c: Coin) => c.exchangeBaseUrl === exchangeBaseUrl) .filter((c: Coin) => c.exchangeBaseUrl === exchangeBaseUrl)
.toArray(); .toArray();
} }
async getPreCoins(exchangeBaseUrl: string): Promise<PreCoin[]> { async getPreCoins(exchangeBaseUrl: string): Promise<PreCoin[]> {
return this.q() return this.q()
.iter<PreCoin>("precoins") .iter<PreCoin>(Stores.precoins)
.filter((c: PreCoin) => c.exchangeBaseUrl === exchangeBaseUrl) .filter((c: PreCoin) => c.exchangeBaseUrl === exchangeBaseUrl)
.toArray(); .toArray();
} }
@ -1431,19 +1446,19 @@ export class Wallet {
async paymentSucceeded(contractHash: string): Promise<any> { async paymentSucceeded(contractHash: string): Promise<any> {
const doPaymentSucceeded = async() => { const doPaymentSucceeded = async() => {
let t = await this.q().get<Transaction>("transactions", contractHash); let t = await this.q().get<Transaction>(Stores.transactions, contractHash);
if (!t) { if (!t) {
console.error("contract not found"); console.error("contract not found");
return; return;
} }
for (let pc of t.payReq.coins) { for (let pc of t.payReq.coins) {
let c = await this.q().get<Coin>("coins", pc.coin_pub); let c = await this.q().get<Coin>(Stores.coins, pc.coin_pub);
if (!c) { if (!c) {
console.error("coin not found"); console.error("coin not found");
return; return;
} }
c.transactionPending = false; c.transactionPending = false;
await this.q().put("coins", c).finish(); await this.q().put(Stores.coins, c).finish();
} }
for (let c of t.payReq.coins) { for (let c of t.payReq.coins) {
this.refresh(c.coin_pub); this.refresh(c.coin_pub);