aboutsummaryrefslogtreecommitdiff
path: root/extension/lib/wallet/wallet.ts
diff options
context:
space:
mode:
Diffstat (limited to 'extension/lib/wallet/wallet.ts')
-rw-r--r--extension/lib/wallet/wallet.ts208
1 files changed, 89 insertions, 119 deletions
diff --git a/extension/lib/wallet/wallet.ts b/extension/lib/wallet/wallet.ts
index cbc3e4b01..62d67b40c 100644
--- a/extension/lib/wallet/wallet.ts
+++ b/extension/lib/wallet/wallet.ts
@@ -32,8 +32,7 @@ import {UInt64} from "./emscriptif";
import {DepositRequestPS} from "./emscriptif";
import {eddsaSign} from "./emscriptif";
import {EddsaPrivateKey} from "./emscriptif";
-import {ConfirmReserveRequest} from "./types";
-import {ConfirmReserveResponse} from "./types";
+import {CreateReserveRequest} from "./types";
import {RsaPublicKey} from "./emscriptif";
import {Denomination} from "./types";
import {RsaBlindingKey} from "./emscriptif";
@@ -48,24 +47,15 @@ import {HttpResponse} from "./http";
import {RequestException} from "./http";
import {Query} from "./query";
import {AmountJson} from "./types";
+import {ConfirmReserveRequest} from "./types";
+import {Offer} from "./types";
+import {Contract} from "./types";
+import {MintInfo} from "./types";
+import {CreateReserveResponse} from "./types";
"use strict";
-
-class CoinPaySig {
- coin_sig: string;
-
- coin_pub: string;
-
- ub_sig: string;
-
- denom_pub: string;
-
- f: AmountJson;
-}
-
-
interface ConfirmPayRequest {
offer: Offer;
}
@@ -75,36 +65,7 @@ interface MintCoins {
}
-interface MintInfo {
- master_pub: string;
- url: string;
-}
-
-interface Offer {
- contract: Contract;
- merchant_sig: string;
- H_contract: string;
-}
-
-interface Contract {
- H_wire: string;
- amount: AmountJson;
- auditors: string[];
- expiry: string,
- locations: string[];
- max_fee: AmountJson;
- merchant: any;
- merchant_pub: string;
- mints: MintInfo[];
- products: string[];
- refund_deadline: string;
- timestamp: string;
- transaction_id: number;
- fulfillment_url: string;
-}
-
-
-interface CoinPaySig_interface {
+interface CoinPaySig {
coin_sig: string;
coin_pub: string;
ub_sig: string;
@@ -127,19 +88,13 @@ interface Reserve {
}
-interface PaymentResponse {
- payReq: any;
- contract: Contract;
-}
-
-
export interface Badge {
setText(s: string): void;
setColor(c: string): void;
}
-type PayCoinInfo = Array<{ updatedCoin: Coin, sig: CoinPaySig_interface }>;
+type PayCoinInfo = Array<{ updatedCoin: Coin, sig: CoinPaySig }>;
/**
@@ -250,7 +205,7 @@ export class Wallet {
EddsaPrivateKey.fromCrock(cd.coin.coinPriv))
.toCrock();
- let s: CoinPaySig_interface = {
+ let s: CoinPaySig = {
coin_sig: coinSig,
coin_pub: cd.coin.coinPub,
ub_sig: cd.coin.denomSig,
@@ -425,6 +380,11 @@ export class Wallet {
});
}
+
+ /**
+ * First fetch information requred to withdraw from the reserve,
+ * then deplete the reserve, withdrawing coins until it is empty.
+ */
initReserve(reserveRecord) {
this.updateMintFromUrl(reserveRecord.mint_base_url)
.then((mint) =>
@@ -447,72 +407,82 @@ export class Wallet {
}
- confirmReserve(req: ConfirmReserveRequest): Promise<ConfirmReserveResponse> {
- let reservePriv = EddsaPrivateKey.create();
- let reservePub = reservePriv.getPublicKey();
- let form = new FormData();
- let now: number = (new Date).getTime();
- form.append(req.field_amount, req.amount_str);
- form.append(req.field_reserve_pub, reservePub.toCrock());
- form.append(req.field_mint, req.mint);
- // TODO: set bank-specified fields.
- let mintBaseUrl = canonicalizeBaseUrl(req.mint);
- let requestedAmount = parsePrettyAmount(req.amount_str);
-
- if (!requestedAmount) {
- throw Error(`unrecognized amount ${req.amount_str}.`);
- }
+ /**
+ * Create a reserve, but do not flag it as confirmed yet.
+ */
+ createReserve(req: CreateReserveRequest): Promise<CreateReserveResponse> {
+ const reservePriv = EddsaPrivateKey.create();
+ const reservePub = reservePriv.getPublicKey();
+
+ const now = (new Date).getTime();
+ const canonMint = canonicalizeBaseUrl(req.mint);
+
+ const reserveRecord = {
+ reserve_pub: reservePub.toCrock(),
+ reserve_priv: reservePriv.toCrock(),
+ mint_base_url: canonMint,
+ created: now,
+ last_query: null,
+ current_amount: null,
+ requested_amount: req.amount,
+ confirmed: false,
+ };
+
+
+ const historyEntry = {
+ type: "create-reserve",
+ timestamp: now,
+ detail: {
+ requestedAmount: req.amount,
+ reservePub: reserveRecord.reserve_pub,
+ }
+ };
+
+ return Query(this.db)
+ .put("reserves", reserveRecord)
+ .put("history", historyEntry)
+ .finish()
+ .then(() => {
+ let r: CreateReserveResponse = {
+ mint: canonMint,
+ reservePub: reservePub.toCrock(),
+ };
+ return r;
+ });
+ }
- return this.http.postForm(req.post_url, form)
- .then((hresp) => {
- // TODO: look at response status code and handle errors appropriately
- let json = JSON.parse(hresp.responseText);
- if (!json) {
- return {
- success: false
- };
- }
- let resp: ConfirmReserveResponse = {
- success: undefined,
- backlink: json.redirect_url,
- };
- let reserveRecord = {
- reserve_pub: reservePub.toCrock(),
- reserve_priv: reservePriv.toCrock(),
- mint_base_url: mintBaseUrl,
- created: now,
- last_query: null,
- current_amount: null,
- // XXX: set to actual amount
- requested_amount: null
- };
-
- if (hresp.status != 200) {
- resp.success = false;
- return resp;
- }
-
- let historyEntry = {
- type: "create-reserve",
- timestamp: now,
- detail: {
- requestedAmount,
- reservePub: reserveRecord.reserve_pub,
- }
- };
-
- resp.success = true;
-
- return Query(this.db)
- .put("reserves", reserveRecord)
- .put("history", historyEntry)
- .finish()
- .then(() => {
- // Do this in the background
- this.initReserve(reserveRecord);
- return resp;
- });
- });
+
+ /**
+ * Mark an existing reserve as confirmed. The wallet will start trying
+ * to withdraw from that reserve. This may not immediately succeed,
+ * since the mint might not know about the reserve yet, even though the
+ * bank confirmed its creation.
+ *
+ * A confirmed reserve should be shown to the user in the UI, while
+ * an unconfirmed reserve should be hidden.
+ */
+ confirmReserve(req: ConfirmReserveRequest): Promise<void> {
+ const now = (new Date).getTime();
+ const historyEntry = {
+ type: "confirm-reserve",
+ timestamp: now,
+ detail: {
+ reservePub: req.reservePub,
+ }
+ };
+ return Query(this.db)
+ .get("reserves", req.reservePub)
+ .then((r) => {
+ r.confirmed = true;
+ return Query(this.db)
+ .put("reserves", r)
+ .put("history", historyEntry)
+ .finish()
+ .then(() => {
+ // Do this in the background
+ this.initReserve(r);
+ });
+ });
}