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: "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: "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: "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: "mouseover", listener: (this: Window, ev: MouseEvent) => any, useCapture?: boolean): void;
|
||||||
declare function addEventListener(type: "mouseup", listener: (this: Window, 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, WheelEvent) => 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, Event) => 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, 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, 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, PageTransitionEvent) => 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, 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, Event) => 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, 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, 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, PointerEvent) => 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, 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, 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, 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, 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, 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, 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, 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, PopStateEvent) => 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, ProgressEvent) => 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, Event) => 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, ProgressEvent) => 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, Event) => 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, UIEvent) => 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, 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, Event) => 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, 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, UIEvent) => 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, Event) => 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, StorageEvent) => 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, Event) => 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, 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, 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, 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, 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, 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, WheelEvent) => 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;
|
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||||
type AAGUID = string;
|
type AAGUID = string;
|
||||||
type AlgorithmIdentifier = string | Algorithm;
|
type AlgorithmIdentifier = string | Algorithm;
|
||||||
|
@ -69,6 +69,8 @@ export interface QueryStream<T> {
|
|||||||
map<S>(f: (x:T) => S): QueryStream<S>;
|
map<S>(f: (x:T) => S): QueryStream<S>;
|
||||||
flatMap<S>(f: (x: T) => S[]): QueryStream<S>;
|
flatMap<S>(f: (x: T) => S[]): QueryStream<S>;
|
||||||
toArray(): Promise<T[]>;
|
toArray(): Promise<T[]>;
|
||||||
|
|
||||||
|
then(onfulfill: any, onreject: any): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let AbortTransaction = Symbol("abort_transaction");
|
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,
|
abstract subscribe(f: (isDone: boolean,
|
||||||
value: any,
|
value: any,
|
||||||
tx: IDBTransaction) => void): void;
|
tx: IDBTransaction) => void): void;
|
||||||
@ -103,11 +105,15 @@ abstract class QueryStreamBase<T> implements QueryStream<T> {
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
flatMap<S>(f: (x: T) => T[]): QueryStream<S> {
|
then<R>(onfulfilled: (value: void) => R | PromiseLike<R>, onrejected: (reason: any) => R | PromiseLike<R>): PromiseLike<R> {
|
||||||
return new QueryStreamFlatMap(this, f);
|
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);
|
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>;
|
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);
|
super(s.root);
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.flatMapFn = flatMapFn;
|
this.flatMapFn = flatMapFn;
|
||||||
@ -218,11 +224,11 @@ class QueryStreamFlatMap<T> extends QueryStreamBase<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class QueryStreamMap<T> extends QueryStreamBase<T> {
|
class QueryStreamMap<S,T> extends QueryStreamBase<T> {
|
||||||
s: QueryStreamBase<T>;
|
s: QueryStreamBase<S>;
|
||||||
mapFn: (v: T) => T[];
|
mapFn: (v: S) => T;
|
||||||
|
|
||||||
constructor(s: QueryStreamBase<T>, mapFn: (v: T) => T[]) {
|
constructor(s: QueryStreamBase<S>, mapFn: (v: S) => T) {
|
||||||
super(s.root);
|
super(s.root);
|
||||||
this.s = s;
|
this.s = s;
|
||||||
this.mapFn = mapFn;
|
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 work: ((t: IDBTransaction) => void)[] = [];
|
||||||
private db: IDBDatabase;
|
private db: IDBDatabase;
|
||||||
private stores = new Set();
|
private stores = new Set();
|
||||||
@ -376,18 +382,26 @@ export class QueryRoot {
|
|||||||
*/
|
*/
|
||||||
private hasWrite: boolean;
|
private hasWrite: boolean;
|
||||||
|
|
||||||
|
private finishScheduled: boolean;
|
||||||
|
|
||||||
constructor(db: IDBDatabase) {
|
constructor(db: IDBDatabase) {
|
||||||
this.db = db;
|
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> {
|
iter<T>(store: Store<T>): QueryStream<T> {
|
||||||
this.stores.add(store.name);
|
this.stores.add(store.name);
|
||||||
|
this.scheduleFinish();
|
||||||
return new IterQueryStream(this, store.name, {});
|
return new IterQueryStream(this, store.name, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
iterIndex<S extends IDBValidKey,T>(index: Index<S,T>,
|
iterIndex<S extends IDBValidKey,T>(index: Index<S,T>,
|
||||||
only?: S): QueryStream<T> {
|
only?: S): QueryStream<T> {
|
||||||
this.stores.add(index.storeName);
|
this.stores.add(index.storeName);
|
||||||
|
this.scheduleFinish();
|
||||||
return new IterQueryStream(this, index.storeName, {
|
return new IterQueryStream(this, index.storeName, {
|
||||||
only,
|
only,
|
||||||
indexName: index.indexName
|
indexName: index.indexName
|
||||||
@ -403,6 +417,7 @@ export class QueryRoot {
|
|||||||
let doPut = (tx: IDBTransaction) => {
|
let doPut = (tx: IDBTransaction) => {
|
||||||
tx.objectStore(store.name).put(val);
|
tx.objectStore(store.name).put(val);
|
||||||
};
|
};
|
||||||
|
this.scheduleFinish();
|
||||||
this.addWork(doPut, store.name, true);
|
this.addWork(doPut, store.name, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -427,6 +442,7 @@ export class QueryRoot {
|
|||||||
tx.objectStore(store.name).put(m);
|
tx.objectStore(store.name).put(m);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.scheduleFinish();
|
||||||
this.addWork(doPut, store.name, true);
|
this.addWork(doPut, store.name, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -443,6 +459,7 @@ export class QueryRoot {
|
|||||||
tx.objectStore(store.name).put(obj);
|
tx.objectStore(store.name).put(obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.scheduleFinish();
|
||||||
this.addWork(doPutAll, store.name, true);
|
this.addWork(doPutAll, store.name, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -456,6 +473,7 @@ export class QueryRoot {
|
|||||||
const doAdd = (tx: IDBTransaction) => {
|
const doAdd = (tx: IDBTransaction) => {
|
||||||
tx.objectStore(store.name).add(val);
|
tx.objectStore(store.name).add(val);
|
||||||
};
|
};
|
||||||
|
this.scheduleFinish();
|
||||||
this.addWork(doAdd, store.name, true);
|
this.addWork(doAdd, store.name, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -509,6 +527,13 @@ export class QueryRoot {
|
|||||||
.then(() => promise);
|
.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.
|
* Finish the query, and start the query in the first place if necessary.
|
||||||
*/
|
*/
|
||||||
@ -543,6 +568,7 @@ export class QueryRoot {
|
|||||||
const doDelete = (tx: IDBTransaction) => {
|
const doDelete = (tx: IDBTransaction) => {
|
||||||
tx.objectStore(storeName).delete(key);
|
tx.objectStore(storeName).delete(key);
|
||||||
};
|
};
|
||||||
|
this.scheduleFinish();
|
||||||
this.addWork(doDelete, storeName, true);
|
this.addWork(doDelete, storeName, true);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,15 @@ export interface ReserveRecord {
|
|||||||
* be higher than the requested_amount
|
* be higher than the requested_amount
|
||||||
*/
|
*/
|
||||||
requested_amount: AmountJson,
|
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,
|
confirmed: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import {
|
|||||||
import {HttpResponse, RequestException} from "./http";
|
import {HttpResponse, RequestException} from "./http";
|
||||||
import {QueryRoot, Store, Index, JoinResult, AbortTransaction} from "./query";
|
import {QueryRoot, Store, Index, JoinResult, AbortTransaction} from "./query";
|
||||||
import {Checkable} from "./checkable";
|
import {Checkable} from "./checkable";
|
||||||
import {canonicalizeBaseUrl} from "./helpers";
|
import {canonicalizeBaseUrl, amountToPretty} from "./helpers";
|
||||||
import {ReserveCreationInfo, Amounts} from "./types";
|
import {ReserveCreationInfo, Amounts} from "./types";
|
||||||
import {PreCoin} from "./types";
|
import {PreCoin} from "./types";
|
||||||
import {CryptoApi} from "./cryptoApi";
|
import {CryptoApi} from "./cryptoApi";
|
||||||
@ -403,10 +403,13 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateExchanges(): void {
|
async updateExchanges(): Promise<void> {
|
||||||
console.log("updating exchanges");
|
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) {
|
for (let url of exchangesUrls) {
|
||||||
this.updateExchangeFromUrl(url)
|
this.updateExchangeFromUrl(url)
|
||||||
@ -766,18 +769,18 @@ export class Wallet {
|
|||||||
const coin = await this.withdrawExecute(preCoin);
|
const coin = await this.withdrawExecute(preCoin);
|
||||||
|
|
||||||
const mutateReserve = (r: ReserveRecord) => {
|
const mutateReserve = (r: ReserveRecord) => {
|
||||||
let currentAmount = r.current_amount;
|
|
||||||
if (!currentAmount) {
|
console.log(`before committing coin: current ${amountToPretty(r.current_amount!)}, precoin: ${amountToPretty(
|
||||||
throw Error("can't withdraw from reserve when current amount is" +
|
r.precoin_amount)})}`);
|
||||||
" unknown");
|
|
||||||
}
|
let x = Amounts.sub(r.precoin_amount,
|
||||||
let x = Amounts.sub(currentAmount,
|
|
||||||
preCoin.coinValue,
|
preCoin.coinValue,
|
||||||
denom!.fee_withdraw);
|
denom!.fee_withdraw);
|
||||||
if (x.saturated) {
|
if (x.saturated) {
|
||||||
|
console.error("database inconsistent");
|
||||||
throw AbortTransaction;
|
throw AbortTransaction;
|
||||||
}
|
}
|
||||||
r.current_amount = x.amount;
|
r.precoin_amount = x.amount;
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -791,7 +794,6 @@ export class Wallet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await this.q()
|
await this.q()
|
||||||
.put(Stores.precoins, preCoin)
|
|
||||||
.mutate(Stores.reserves, preCoin.reservePub, mutateReserve)
|
.mutate(Stores.reserves, preCoin.reservePub, mutateReserve)
|
||||||
.delete("precoins", coin.coinPub)
|
.delete("precoins", coin.coinPub)
|
||||||
.add(Stores.coins, coin)
|
.add(Stores.coins, coin)
|
||||||
@ -828,7 +830,7 @@ export class Wallet {
|
|||||||
current_amount: null,
|
current_amount: null,
|
||||||
requested_amount: req.amount,
|
requested_amount: req.amount,
|
||||||
confirmed: false,
|
confirmed: false,
|
||||||
withdrawn_amount: Amounts.getZero(req.amount.currency)
|
precoin_amount: Amounts.getZero(req.amount.currency),
|
||||||
};
|
};
|
||||||
|
|
||||||
const historyEntry = {
|
const historyEntry = {
|
||||||
@ -940,17 +942,47 @@ export class Wallet {
|
|||||||
/**
|
/**
|
||||||
* Withdraw coins from a reserve until it is empty.
|
* Withdraw coins from a reserve until it is empty.
|
||||||
*/
|
*/
|
||||||
private async depleteReserve(reserve: any,
|
private async depleteReserve(reserve: ReserveRecord,
|
||||||
exchange: IExchangeInfo): Promise<number> {
|
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 denomsAvailable: Denomination[] = copy(exchange.active_denoms);
|
||||||
let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount,
|
let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount!,
|
||||||
denomsAvailable);
|
denomsAvailable);
|
||||||
|
|
||||||
let ps = denomsForWithdraw.map(async(denom) => {
|
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
|
let preCoin = await this.cryptoApi
|
||||||
.createPreCoin(denom, reserve);
|
.createPreCoin(denom, reserve);
|
||||||
|
await this.q()
|
||||||
|
.put(Stores.precoins, preCoin)
|
||||||
|
.mutate(Stores.reserves, reserve.reserve_pub, mutateReserve);
|
||||||
await this.processPreCoin(preCoin);
|
await this.processPreCoin(preCoin);
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(ps);
|
await Promise.all(ps);
|
||||||
return ps.length;
|
return ps.length;
|
||||||
}
|
}
|
||||||
@ -1219,6 +1251,7 @@ export class Wallet {
|
|||||||
if (!amount) {
|
if (!amount) {
|
||||||
amount = r.requested_amount;
|
amount = r.requested_amount;
|
||||||
}
|
}
|
||||||
|
amount = Amounts.add(amount, r.precoin_amount).amount;
|
||||||
if (Amounts.cmp(smallestWithdraw[r.exchange_base_url], amount) < 0) {
|
if (Amounts.cmp(smallestWithdraw[r.exchange_base_url], amount) < 0) {
|
||||||
entry.pendingIncoming = Amounts.add(entry.pendingIncoming,
|
entry.pendingIncoming = Amounts.add(entry.pendingIncoming,
|
||||||
amount).amount;
|
amount).amount;
|
||||||
@ -1333,7 +1366,7 @@ export class Wallet {
|
|||||||
oldDenom.fee_refresh));
|
oldDenom.fee_refresh));
|
||||||
|
|
||||||
function mutateCoin(c: Coin): Coin {
|
function mutateCoin(c: Coin): Coin {
|
||||||
let r = Amounts.sub(coin.currentAmount,
|
let r = Amounts.sub(c.currentAmount,
|
||||||
refreshSession.valueWithFee);
|
refreshSession.valueWithFee);
|
||||||
if (r.saturated) {
|
if (r.saturated) {
|
||||||
// Something else must have written the coin value
|
// 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.`;
|
return i18n`Error: could not retrieve balance information.`;
|
||||||
}
|
}
|
||||||
if (!wallet) {
|
if (!wallet) {
|
||||||
return this.renderEmpty();
|
return <span></span>;
|
||||||
}
|
}
|
||||||
console.log(wallet);
|
console.log(wallet);
|
||||||
let listing = Object.keys(wallet).map((key) => {
|
let listing = Object.keys(wallet).map((key) => {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"test/tests/taler.ts",
|
"test/tests/taler.ts",
|
||||||
"lib/refs.d.ts",
|
"lib/refs.d.ts",
|
||||||
"lib/i18n.ts",
|
"lib/i18n.ts",
|
||||||
"lib/shopApi.ts",
|
|
||||||
"lib/taler-wallet-lib.ts",
|
"lib/taler-wallet-lib.ts",
|
||||||
"lib/wallet/checkable.ts",
|
"lib/wallet/checkable.ts",
|
||||||
"lib/wallet/chromeBadge.ts",
|
"lib/wallet/chromeBadge.ts",
|
||||||
|
Loading…
Reference in New Issue
Block a user