make queries then-able
This commit is contained in:
parent
9ee0823b7e
commit
de65019ed6
76
lib/decl/lib.es6.d.ts
vendored
76
lib/decl/lib.es6.d.ts
vendored
@ -20288,44 +20288,44 @@ declare function addEventListener(type: "mouseenter", listener: (this: Window, e
|
||||
declare function addEventListener(type: "mouseleave", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mousemove", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mouseout", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mouseover", listener: (this: Window, MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mouseup", listener: (this: Window, MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mousewheel", listener: (this: Window, WheelEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "offline", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "online", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "orientationchange", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pagehide", listener: (this: Window, PageTransitionEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pageshow", listener: (this: Window, PageTransitionEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pause", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "play", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "playing", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointercancel", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerdown", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerenter", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerleave", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointermove", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerout", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerover", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerup", listener: (this: Window, PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "popstate", listener: (this: Window, PopStateEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "progress", listener: (this: Window, ProgressEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "ratechange", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "readystatechange", listener: (this: Window, ProgressEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "reset", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "resize", listener: (this: Window, UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "scroll", listener: (this: Window, UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "seeked", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "seeking", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "select", listener: (this: Window, UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "stalled", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "storage", listener: (this: Window, StorageEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "submit", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "suspend", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "timeupdate", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "unload", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "volumechange", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "waiting", listener: (this: Window, Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "wheel", listener: (this: Window, WheelEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mouseover", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mouseup", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "mousewheel", listener: (this: Window, ev: WheelEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "offline", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "online", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "orientationchange", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pagehide", listener: (this: Window, ev: PageTransitionEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pageshow", listener: (this: Window, ev: PageTransitionEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pause", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "play", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "playing", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointercancel", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerdown", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerenter", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerleave", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointermove", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerout", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerover", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "pointerup", listener: (this: Window, ev: PointerEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "popstate", listener: (this: Window, ev: PopStateEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "progress", listener: (this: Window, ev: ProgressEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "ratechange", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "readystatechange", listener: (this: Window, ev: ProgressEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "reset", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "resize", listener: (this: Window, ev: UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "scroll", listener: (this: Window, ev: UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "seeked", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "seeking", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "select", listener: (this: Window, ev: UIEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "stalled", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "storage", listener: (this: Window, ev: StorageEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "submit", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "suspend", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "timeupdate", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "unload", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "volumechange", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "waiting", listener: (this: Window, ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "wheel", listener: (this: Window, ev: WheelEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
type AAGUID = string;
|
||||
type AlgorithmIdentifier = string | Algorithm;
|
||||
|
@ -69,6 +69,8 @@ export interface QueryStream<T> {
|
||||
map<S>(f: (x:T) => S): QueryStream<S>;
|
||||
flatMap<S>(f: (x: T) => S[]): QueryStream<S>;
|
||||
toArray(): Promise<T[]>;
|
||||
|
||||
then(onfulfill: any, onreject: any): any;
|
||||
}
|
||||
|
||||
export let AbortTransaction = Symbol("abort_transaction");
|
||||
@ -92,7 +94,7 @@ function openPromise<T>() {
|
||||
}
|
||||
|
||||
|
||||
abstract class QueryStreamBase<T> implements QueryStream<T> {
|
||||
abstract class QueryStreamBase<T> implements QueryStream<T>, PromiseLike<void> {
|
||||
abstract subscribe(f: (isDone: boolean,
|
||||
value: any,
|
||||
tx: IDBTransaction) => void): void;
|
||||
@ -103,11 +105,15 @@ abstract class QueryStreamBase<T> implements QueryStream<T> {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
flatMap<S>(f: (x: T) => T[]): QueryStream<S> {
|
||||
return new QueryStreamFlatMap(this, f);
|
||||
then<R>(onfulfilled: (value: void) => R | PromiseLike<R>, onrejected: (reason: any) => R | PromiseLike<R>): PromiseLike<R> {
|
||||
return this.root.then(onfulfilled, onrejected);
|
||||
}
|
||||
|
||||
map<S>(f: (x: T) => S): QueryStream<T> {
|
||||
flatMap<S>(f: (x: T) => S[]): QueryStream<S> {
|
||||
return new QueryStreamFlatMap<T,S>(this, f);
|
||||
}
|
||||
|
||||
map<S>(f: (x: T) => S): QueryStream<S> {
|
||||
return new QueryStreamMap(this, f);
|
||||
}
|
||||
|
||||
@ -193,11 +199,11 @@ class QueryStreamFilter<T> extends QueryStreamBase<T> {
|
||||
}
|
||||
|
||||
|
||||
class QueryStreamFlatMap<T> extends QueryStreamBase<T> {
|
||||
class QueryStreamFlatMap<T,S> extends QueryStreamBase<S> {
|
||||
s: QueryStreamBase<T>;
|
||||
flatMapFn: (v: T) => T[];
|
||||
flatMapFn: (v: T) => S[];
|
||||
|
||||
constructor(s: QueryStreamBase<T>, flatMapFn: (v: T) => T[]) {
|
||||
constructor(s: QueryStreamBase<T>, flatMapFn: (v: T) => S[]) {
|
||||
super(s.root);
|
||||
this.s = s;
|
||||
this.flatMapFn = flatMapFn;
|
||||
@ -218,11 +224,11 @@ class QueryStreamFlatMap<T> extends QueryStreamBase<T> {
|
||||
}
|
||||
|
||||
|
||||
class QueryStreamMap<T> extends QueryStreamBase<T> {
|
||||
s: QueryStreamBase<T>;
|
||||
mapFn: (v: T) => T[];
|
||||
class QueryStreamMap<S,T> extends QueryStreamBase<T> {
|
||||
s: QueryStreamBase<S>;
|
||||
mapFn: (v: S) => T;
|
||||
|
||||
constructor(s: QueryStreamBase<T>, mapFn: (v: T) => T[]) {
|
||||
constructor(s: QueryStreamBase<S>, mapFn: (v: S) => T) {
|
||||
super(s.root);
|
||||
this.s = s;
|
||||
this.mapFn = mapFn;
|
||||
@ -364,7 +370,7 @@ class IterQueryStream<T> extends QueryStreamBase<T> {
|
||||
}
|
||||
|
||||
|
||||
export class QueryRoot {
|
||||
export class QueryRoot implements PromiseLike<void> {
|
||||
private work: ((t: IDBTransaction) => void)[] = [];
|
||||
private db: IDBDatabase;
|
||||
private stores = new Set();
|
||||
@ -376,18 +382,26 @@ export class QueryRoot {
|
||||
*/
|
||||
private hasWrite: boolean;
|
||||
|
||||
private finishScheduled: boolean;
|
||||
|
||||
constructor(db: IDBDatabase) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
then<R>(onfulfilled: (value: void) => R | PromiseLike<R>, onrejected: (reason: any) => R | PromiseLike<R>): PromiseLike<R> {
|
||||
return this.finish().then(onfulfilled, onrejected);
|
||||
}
|
||||
|
||||
iter<T>(store: Store<T>): QueryStream<T> {
|
||||
this.stores.add(store.name);
|
||||
this.scheduleFinish();
|
||||
return new IterQueryStream(this, store.name, {});
|
||||
}
|
||||
|
||||
iterIndex<S extends IDBValidKey,T>(index: Index<S,T>,
|
||||
only?: S): QueryStream<T> {
|
||||
this.stores.add(index.storeName);
|
||||
this.scheduleFinish();
|
||||
return new IterQueryStream(this, index.storeName, {
|
||||
only,
|
||||
indexName: index.indexName
|
||||
@ -403,6 +417,7 @@ export class QueryRoot {
|
||||
let doPut = (tx: IDBTransaction) => {
|
||||
tx.objectStore(store.name).put(val);
|
||||
};
|
||||
this.scheduleFinish();
|
||||
this.addWork(doPut, store.name, true);
|
||||
return this;
|
||||
}
|
||||
@ -427,6 +442,7 @@ export class QueryRoot {
|
||||
tx.objectStore(store.name).put(m);
|
||||
}
|
||||
};
|
||||
this.scheduleFinish();
|
||||
this.addWork(doPut, store.name, true);
|
||||
return this;
|
||||
}
|
||||
@ -443,6 +459,7 @@ export class QueryRoot {
|
||||
tx.objectStore(store.name).put(obj);
|
||||
}
|
||||
};
|
||||
this.scheduleFinish();
|
||||
this.addWork(doPutAll, store.name, true);
|
||||
return this;
|
||||
}
|
||||
@ -456,6 +473,7 @@ export class QueryRoot {
|
||||
const doAdd = (tx: IDBTransaction) => {
|
||||
tx.objectStore(store.name).add(val);
|
||||
};
|
||||
this.scheduleFinish();
|
||||
this.addWork(doAdd, store.name, true);
|
||||
return this;
|
||||
}
|
||||
@ -509,6 +527,13 @@ export class QueryRoot {
|
||||
.then(() => promise);
|
||||
}
|
||||
|
||||
private scheduleFinish() {
|
||||
if (!this.finishScheduled) {
|
||||
Promise.resolve().then(() => this.finish());
|
||||
this.finishScheduled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the query, and start the query in the first place if necessary.
|
||||
*/
|
||||
@ -543,6 +568,7 @@ export class QueryRoot {
|
||||
const doDelete = (tx: IDBTransaction) => {
|
||||
tx.objectStore(storeName).delete(key);
|
||||
};
|
||||
this.scheduleFinish();
|
||||
this.addWork(doDelete, storeName, true);
|
||||
return this;
|
||||
}
|
||||
|
@ -64,10 +64,15 @@ export interface ReserveRecord {
|
||||
* be higher than the requested_amount
|
||||
*/
|
||||
requested_amount: AmountJson,
|
||||
|
||||
|
||||
/**
|
||||
* Amount we've already withdrawn from the reserve.
|
||||
* What's the current amount that sits
|
||||
* in precoins?
|
||||
*/
|
||||
withdrawn_amount: AmountJson;
|
||||
precoin_amount: AmountJson;
|
||||
|
||||
|
||||
confirmed: boolean,
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
import {HttpResponse, RequestException} from "./http";
|
||||
import {QueryRoot, Store, Index, JoinResult, AbortTransaction} from "./query";
|
||||
import {Checkable} from "./checkable";
|
||||
import {canonicalizeBaseUrl} from "./helpers";
|
||||
import {canonicalizeBaseUrl, amountToPretty} from "./helpers";
|
||||
import {ReserveCreationInfo, Amounts} from "./types";
|
||||
import {PreCoin} from "./types";
|
||||
import {CryptoApi} from "./cryptoApi";
|
||||
@ -403,10 +403,13 @@ export class Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
updateExchanges(): void {
|
||||
async updateExchanges(): Promise<void> {
|
||||
console.log("updating exchanges");
|
||||
|
||||
let exchangesUrls = this.q().iter(Stores.exchanges).map((e) => e.baseUrl);
|
||||
let exchangesUrls = await this.q()
|
||||
.iter(Stores.exchanges)
|
||||
.map((e) => e.baseUrl)
|
||||
.toArray();
|
||||
|
||||
for (let url of exchangesUrls) {
|
||||
this.updateExchangeFromUrl(url)
|
||||
@ -766,18 +769,18 @@ export class Wallet {
|
||||
const coin = await this.withdrawExecute(preCoin);
|
||||
|
||||
const mutateReserve = (r: ReserveRecord) => {
|
||||
let currentAmount = r.current_amount;
|
||||
if (!currentAmount) {
|
||||
throw Error("can't withdraw from reserve when current amount is" +
|
||||
" unknown");
|
||||
}
|
||||
let x = Amounts.sub(currentAmount,
|
||||
|
||||
console.log(`before committing coin: current ${amountToPretty(r.current_amount!)}, precoin: ${amountToPretty(
|
||||
r.precoin_amount)})}`);
|
||||
|
||||
let x = Amounts.sub(r.precoin_amount,
|
||||
preCoin.coinValue,
|
||||
denom!.fee_withdraw);
|
||||
if (x.saturated) {
|
||||
console.error("database inconsistent");
|
||||
throw AbortTransaction;
|
||||
}
|
||||
r.current_amount = x.amount;
|
||||
r.precoin_amount = x.amount;
|
||||
return r;
|
||||
};
|
||||
|
||||
@ -791,7 +794,6 @@ export class Wallet {
|
||||
};
|
||||
|
||||
await this.q()
|
||||
.put(Stores.precoins, preCoin)
|
||||
.mutate(Stores.reserves, preCoin.reservePub, mutateReserve)
|
||||
.delete("precoins", coin.coinPub)
|
||||
.add(Stores.coins, coin)
|
||||
@ -828,7 +830,7 @@ export class Wallet {
|
||||
current_amount: null,
|
||||
requested_amount: req.amount,
|
||||
confirmed: false,
|
||||
withdrawn_amount: Amounts.getZero(req.amount.currency)
|
||||
precoin_amount: Amounts.getZero(req.amount.currency),
|
||||
};
|
||||
|
||||
const historyEntry = {
|
||||
@ -940,17 +942,47 @@ export class Wallet {
|
||||
/**
|
||||
* Withdraw coins from a reserve until it is empty.
|
||||
*/
|
||||
private async depleteReserve(reserve: any,
|
||||
private async depleteReserve(reserve: ReserveRecord,
|
||||
exchange: IExchangeInfo): Promise<number> {
|
||||
if (!reserve.current_amount) {
|
||||
throw Error("can't withdraw when amount is unknown");
|
||||
}
|
||||
let denomsAvailable: Denomination[] = copy(exchange.active_denoms);
|
||||
let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount,
|
||||
let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount!,
|
||||
denomsAvailable);
|
||||
|
||||
let ps = denomsForWithdraw.map(async(denom) => {
|
||||
function mutateReserve(r: ReserveRecord): ReserveRecord {
|
||||
let currentAmount = r.current_amount;
|
||||
if (!currentAmount) {
|
||||
throw Error("can't withdraw when amount is unknown");
|
||||
}
|
||||
r.precoin_amount = Amounts.add(r.precoin_amount,
|
||||
denom.value,
|
||||
denom.fee_withdraw).amount;
|
||||
let result = Amounts.sub(currentAmount,
|
||||
denom.value,
|
||||
denom.fee_withdraw);
|
||||
if (result.saturated) {
|
||||
console.error("can't create precoin, saturated");
|
||||
throw AbortTransaction;
|
||||
}
|
||||
r.current_amount = result.amount;
|
||||
|
||||
console.log(`after creating precoin: current ${amountToPretty(r.current_amount)}, precoin: ${amountToPretty(
|
||||
r.precoin_amount)})}`);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
let preCoin = await this.cryptoApi
|
||||
.createPreCoin(denom, reserve);
|
||||
await this.q()
|
||||
.put(Stores.precoins, preCoin)
|
||||
.mutate(Stores.reserves, reserve.reserve_pub, mutateReserve);
|
||||
await this.processPreCoin(preCoin);
|
||||
});
|
||||
|
||||
await Promise.all(ps);
|
||||
return ps.length;
|
||||
}
|
||||
@ -1219,6 +1251,7 @@ export class Wallet {
|
||||
if (!amount) {
|
||||
amount = r.requested_amount;
|
||||
}
|
||||
amount = Amounts.add(amount, r.precoin_amount).amount;
|
||||
if (Amounts.cmp(smallestWithdraw[r.exchange_base_url], amount) < 0) {
|
||||
entry.pendingIncoming = Amounts.add(entry.pendingIncoming,
|
||||
amount).amount;
|
||||
@ -1333,7 +1366,7 @@ export class Wallet {
|
||||
oldDenom.fee_refresh));
|
||||
|
||||
function mutateCoin(c: Coin): Coin {
|
||||
let r = Amounts.sub(coin.currentAmount,
|
||||
let r = Amounts.sub(c.currentAmount,
|
||||
refreshSession.valueWithFee);
|
||||
if (r.saturated) {
|
||||
// Something else must have written the coin value
|
||||
|
@ -270,7 +270,7 @@ class WalletBalanceView extends preact.Component<any, any> {
|
||||
return i18n`Error: could not retrieve balance information.`;
|
||||
}
|
||||
if (!wallet) {
|
||||
return this.renderEmpty();
|
||||
return <span></span>;
|
||||
}
|
||||
console.log(wallet);
|
||||
let listing = Object.keys(wallet).map((key) => {
|
||||
|
@ -17,7 +17,6 @@
|
||||
"test/tests/taler.ts",
|
||||
"lib/refs.d.ts",
|
||||
"lib/i18n.ts",
|
||||
"lib/shopApi.ts",
|
||||
"lib/taler-wallet-lib.ts",
|
||||
"lib/wallet/checkable.ts",
|
||||
"lib/wallet/chromeBadge.ts",
|
||||
|
Loading…
Reference in New Issue
Block a user