mint->exchange
This commit is contained in:
parent
65eabbf6da
commit
9a197d619c
@ -45,7 +45,6 @@ var TalerNotify;
|
||||
amount: JSON.stringify(e.detail.amount),
|
||||
callback_url: URI(e.detail.callback_url).absoluteTo(document.location.href),
|
||||
bank_url: document.location.href,
|
||||
suggested_mint: e.detail.suggested_mint,
|
||||
};
|
||||
var uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html"));
|
||||
document.location.href = uri.query(params).href();
|
||||
|
@ -8472,7 +8472,7 @@ function _TALER_WRALL_sign_deposit_permission($h_contract,$h_wire,$timestamp,$re
|
||||
}
|
||||
return (0)|0;
|
||||
}
|
||||
function _TALER_WR_verify_confirmation($h_contract,$h_wire,$timestamp,$refund,$0,$1,$amount_minus_fee,$coin_pub,$merchant_pub,$sig,$mint_pub) {
|
||||
function _TALER_WR_verify_confirmation($h_contract,$h_wire,$timestamp,$refund,$0,$1,$amount_minus_fee,$coin_pub,$merchant_pub,$sig,$exchange_pub) {
|
||||
$h_contract = $h_contract|0;
|
||||
$h_wire = $h_wire|0;
|
||||
$timestamp = $timestamp|0;
|
||||
@ -8483,7 +8483,7 @@ function _TALER_WR_verify_confirmation($h_contract,$h_wire,$timestamp,$refund,$0
|
||||
$coin_pub = $coin_pub|0;
|
||||
$merchant_pub = $merchant_pub|0;
|
||||
$sig = $sig|0;
|
||||
$mint_pub = $mint_pub|0;
|
||||
$exchange_pub = $exchange_pub|0;
|
||||
var $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $25 = 0, $26 = 0, $27 = 0, $28 = 0;
|
||||
var $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0;
|
||||
var $47 = 0, $48 = 0, $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, $58 = 0, $59 = 0, $6 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0;
|
||||
@ -8514,7 +8514,7 @@ function _TALER_WR_verify_confirmation($h_contract,$h_wire,$timestamp,$refund,$0
|
||||
$9 = $coin_pub;
|
||||
$10 = $merchant_pub;
|
||||
$11 = $sig;
|
||||
$12 = $mint_pub;
|
||||
$12 = $exchange_pub;
|
||||
$19 = ((($dc)) + 8|0);
|
||||
$20 = $3;
|
||||
dest=$19; src=$20; stop=dest+64|0; do { HEAP8[dest>>0]=HEAP8[src>>0]|0; dest=dest+1|0; src=src+1|0; } while ((dest|0) < (stop|0));
|
||||
|
@ -101,7 +101,7 @@ namespace RpcFunctions {
|
||||
coinPub: coinPub.toCrock(),
|
||||
coinPriv: coinPriv.toCrock(),
|
||||
denomPub: denomPub.encode().toCrock(),
|
||||
mintBaseUrl: reserve.mint_base_url,
|
||||
exchangeBaseUrl: reserve.exchange_base_url,
|
||||
withdrawSig: sig.toCrock(),
|
||||
coinEv: ev.toCrock(),
|
||||
coinValue: denom.value
|
||||
|
@ -45,12 +45,12 @@ export function openTalerDb(): Promise<IDBDatabase> {
|
||||
console.log("DB: upgrade needed: oldVersion = " + e.oldVersion);
|
||||
switch (e.oldVersion) {
|
||||
case 0: // DB does not exist yet
|
||||
const mints = db.createObjectStore("mints", {keyPath: "baseUrl"});
|
||||
mints.createIndex("pubKey", "masterPublicKey");
|
||||
const exchanges = db.createObjectStore("exchanges", {keyPath: "baseUrl"});
|
||||
exchanges.createIndex("pubKey", "masterPublicKey");
|
||||
db.createObjectStore("reserves", {keyPath: "reserve_pub"});
|
||||
db.createObjectStore("denoms", {keyPath: "denomPub"});
|
||||
const coins = db.createObjectStore("coins", {keyPath: "coinPub"});
|
||||
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||
coins.createIndex("exchangeBaseUrl", "exchangeBaseUrl");
|
||||
const transactions = db.createObjectStore("transactions",
|
||||
{keyPath: "contractHash"});
|
||||
transactions.createIndex("repurchase",
|
||||
|
@ -36,7 +36,7 @@ export function amountToPretty(amount: AmountJson): string {
|
||||
|
||||
|
||||
/**
|
||||
* Canonicalize a base url, typically for the mint.
|
||||
* Canonicalize a base url, typically for the exchange.
|
||||
*
|
||||
* See http://api.taler.net/wallet.html#general
|
||||
*/
|
||||
@ -62,4 +62,4 @@ export function parsePrettyAmount(pretty: string): AmountJson {
|
||||
fraction: res[2] ? (parseFloat(`0.${res[2]}`) * 1e-6) : 0,
|
||||
currency: res[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +43,11 @@ export class AmountJson {
|
||||
@Checkable.Class
|
||||
export class CreateReserveResponse {
|
||||
/**
|
||||
* Mint URL where the bank should create the reserve.
|
||||
* Exchange URL where the bank should create the reserve.
|
||||
* The URL is canonicalized in the response.
|
||||
*/
|
||||
@Checkable.String
|
||||
mint: string;
|
||||
exchange: string;
|
||||
|
||||
@Checkable.String
|
||||
reservePub: string;
|
||||
@ -95,14 +95,14 @@ export class Denomination {
|
||||
}
|
||||
|
||||
|
||||
export interface IMintInfo {
|
||||
export interface IExchangeInfo {
|
||||
baseUrl: string;
|
||||
masterPublicKey: string;
|
||||
denoms: Denomination[];
|
||||
}
|
||||
|
||||
export interface ReserveCreationInfo {
|
||||
mintInfo: IMintInfo;
|
||||
exchangeInfo: IExchangeInfo;
|
||||
selectedDenoms: Denomination[];
|
||||
withdrawFee: AmountJson;
|
||||
overhead: AmountJson;
|
||||
@ -117,13 +117,13 @@ export interface PreCoin {
|
||||
blindingKey: string;
|
||||
withdrawSig: string;
|
||||
coinEv: string;
|
||||
mintBaseUrl: string;
|
||||
exchangeBaseUrl: string;
|
||||
coinValue: AmountJson;
|
||||
}
|
||||
|
||||
|
||||
export interface Reserve {
|
||||
mint_base_url: string
|
||||
exchange_base_url: string
|
||||
reserve_priv: string;
|
||||
reserve_pub: string;
|
||||
}
|
||||
@ -144,7 +144,7 @@ export interface Coin {
|
||||
denomPub: string;
|
||||
denomSig: string;
|
||||
currentAmount: AmountJson;
|
||||
mintBaseUrl: string;
|
||||
exchangeBaseUrl: string;
|
||||
}
|
||||
|
||||
|
||||
@ -266,4 +266,4 @@ export interface CheckRepurchaseResult {
|
||||
|
||||
export interface Notifier {
|
||||
notify();
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
* @author Florian Dold
|
||||
*/
|
||||
|
||||
import {AmountJson, CreateReserveResponse, IMintInfo, Denomination, Notifier} from "./types";
|
||||
import {AmountJson, CreateReserveResponse, IExchangeInfo, Denomination, Notifier} from "./types";
|
||||
import {HttpResponse, RequestException} from "./http";
|
||||
import {Query} from "./query";
|
||||
import {Checkable} from "./checkable";
|
||||
@ -70,7 +70,7 @@ export class KeysJson {
|
||||
}
|
||||
|
||||
|
||||
class MintInfo implements IMintInfo {
|
||||
class ExchangeInfo implements IExchangeInfo {
|
||||
baseUrl: string;
|
||||
masterPublicKey: string;
|
||||
denoms: Denomination[];
|
||||
@ -89,15 +89,15 @@ class MintInfo implements IMintInfo {
|
||||
}
|
||||
}
|
||||
|
||||
static fresh(baseUrl: string): MintInfo {
|
||||
return new MintInfo({baseUrl});
|
||||
static fresh(baseUrl: string): ExchangeInfo {
|
||||
return new ExchangeInfo({baseUrl});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new key information into the mint info.
|
||||
* Merge new key information into the exchange info.
|
||||
* If the new key information is invalid (missing fields,
|
||||
* invalid signatures), an exception is thrown, but the
|
||||
* mint info is updated with the new information up until
|
||||
* exchange info is updated with the new information up until
|
||||
* the first error.
|
||||
*/
|
||||
mergeKeys(newKeys: KeysJson, cryptoApi: CryptoApi): Promise<void> {
|
||||
@ -160,10 +160,10 @@ export class CreateReserveRequest {
|
||||
amount: AmountJson;
|
||||
|
||||
/**
|
||||
* Mint URL where the bank should create the reserve.
|
||||
* Exchange URL where the bank should create the reserve.
|
||||
*/
|
||||
@Checkable.String
|
||||
mint: string;
|
||||
exchange: string;
|
||||
|
||||
static checked: (obj: any) => CreateReserveRequest;
|
||||
}
|
||||
@ -183,14 +183,14 @@ export class ConfirmReserveRequest {
|
||||
|
||||
|
||||
@Checkable.Class
|
||||
export class MintHandle {
|
||||
export class ExchangeHandle {
|
||||
@Checkable.String
|
||||
master_pub: string;
|
||||
|
||||
@Checkable.String
|
||||
url: string;
|
||||
|
||||
static checked: (obj: any) => MintHandle;
|
||||
static checked: (obj: any) => ExchangeHandle;
|
||||
}
|
||||
|
||||
|
||||
@ -220,8 +220,8 @@ export class Contract {
|
||||
@Checkable.String
|
||||
merchant_pub: string;
|
||||
|
||||
@Checkable.List(Checkable.Value(MintHandle))
|
||||
mints: MintHandle[];
|
||||
@Checkable.List(Checkable.Value(ExchangeHandle))
|
||||
exchanges: ExchangeHandle[];
|
||||
|
||||
@Checkable.List(Checkable.AnyObject)
|
||||
products: any[];
|
||||
@ -264,8 +264,8 @@ interface ConfirmPayRequest {
|
||||
offer: Offer;
|
||||
}
|
||||
|
||||
interface MintCoins {
|
||||
[mintUrl: string]: CoinWithDenom[];
|
||||
interface ExchangeCoins {
|
||||
[exchangeUrl: string]: CoinWithDenom[];
|
||||
}
|
||||
|
||||
|
||||
@ -402,22 +402,22 @@ export class Wallet {
|
||||
|
||||
|
||||
/**
|
||||
* Get mints and associated coins that are still spendable,
|
||||
* Get exchanges and associated coins that are still spendable,
|
||||
* but only if the sum the coins' remaining value exceeds the payment amount.
|
||||
*/
|
||||
private getPossibleMintCoins(paymentAmount: AmountJson,
|
||||
private getPossibleExchangeCoins(paymentAmount: AmountJson,
|
||||
depositFeeLimit: AmountJson,
|
||||
allowedMints: MintHandle[]): Promise<MintCoins> {
|
||||
// Mapping from mint base URL to list of coins together with their
|
||||
allowedExchanges: ExchangeHandle[]): Promise<ExchangeCoins> {
|
||||
// Mapping from exchange base URL to list of coins together with their
|
||||
// denomination
|
||||
let m: MintCoins = {};
|
||||
let m: ExchangeCoins = {};
|
||||
|
||||
function storeMintCoin(mc) {
|
||||
let mint: IMintInfo = mc[0];
|
||||
function storeExchangeCoin(mc) {
|
||||
let exchange: IExchangeInfo = mc[0];
|
||||
let coin: Coin = mc[1];
|
||||
let cd = {
|
||||
coin: coin,
|
||||
denom: mint.denoms.find((e) => e.denom_pub === coin.denomPub)
|
||||
denom: exchange.denoms.find((e) => e.denom_pub === coin.denomPub)
|
||||
};
|
||||
if (!cd.denom) {
|
||||
throw Error("denom not found (database inconsistent)");
|
||||
@ -426,36 +426,36 @@ export class Wallet {
|
||||
console.warn("same pubkey for different currencies");
|
||||
return;
|
||||
}
|
||||
let x = m[mint.baseUrl];
|
||||
let x = m[exchange.baseUrl];
|
||||
if (!x) {
|
||||
m[mint.baseUrl] = [cd];
|
||||
m[exchange.baseUrl] = [cd];
|
||||
} else {
|
||||
x.push(cd);
|
||||
}
|
||||
}
|
||||
|
||||
let ps = allowedMints.map((info) => {
|
||||
console.log("Checking for merchant's mint", JSON.stringify(info));
|
||||
let ps = allowedExchanges.map((info) => {
|
||||
console.log("Checking for merchant's exchange", JSON.stringify(info));
|
||||
return Query(this.db)
|
||||
.iter("mints", {indexName: "pubKey", only: info.master_pub})
|
||||
.indexJoin("coins", "mintBaseUrl", (mint) => mint.baseUrl)
|
||||
.reduce(storeMintCoin);
|
||||
.iter("exchanges", {indexName: "pubKey", only: info.master_pub})
|
||||
.indexJoin("coins", "exchangeBaseUrl", (exchange) => exchange.baseUrl)
|
||||
.reduce(storeExchangeCoin);
|
||||
});
|
||||
|
||||
return Promise.all(ps).then(() => {
|
||||
let ret: MintCoins = {};
|
||||
let ret: ExchangeCoins = {};
|
||||
|
||||
if (Object.keys(m).length == 0) {
|
||||
console.log("not suitable mints found");
|
||||
console.log("not suitable exchanges found");
|
||||
}
|
||||
|
||||
console.dir(m);
|
||||
|
||||
// We try to find the first mint where we have
|
||||
// We try to find the first exchange where we have
|
||||
// enough coins to cover the paymentAmount with fees
|
||||
// under depositFeeLimit
|
||||
|
||||
nextMint:
|
||||
nextExchange:
|
||||
for (let key in m) {
|
||||
let coins = m[key];
|
||||
// Sort by ascending deposit fee
|
||||
@ -479,12 +479,12 @@ export class Wallet {
|
||||
// FIXME: if the fees are too high, we have
|
||||
// to cover them ourselves ....
|
||||
console.log("too much fees");
|
||||
continue nextMint;
|
||||
continue nextExchange;
|
||||
}
|
||||
usableCoins.push(coins[i]);
|
||||
if (Amounts.cmp(accAmount, minAmount) >= 0) {
|
||||
ret[key] = usableCoins;
|
||||
continue nextMint;
|
||||
continue nextExchange;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -499,14 +499,14 @@ export class Wallet {
|
||||
*/
|
||||
private recordConfirmPay(offer: Offer,
|
||||
payCoinInfo: PayCoinInfo,
|
||||
chosenMint: string): Promise<void> {
|
||||
chosenExchange: string): Promise<void> {
|
||||
let payReq = {};
|
||||
payReq["amount"] = offer.contract.amount;
|
||||
payReq["coins"] = payCoinInfo.map((x) => x.sig);
|
||||
payReq["H_contract"] = offer.H_contract;
|
||||
payReq["max_fee"] = offer.contract.max_fee;
|
||||
payReq["merchant_sig"] = offer.merchant_sig;
|
||||
payReq["mint"] = URI(chosenMint).href();
|
||||
payReq["exchange"] = URI(chosenExchange).href();
|
||||
payReq["refund_deadline"] = offer.contract.refund_deadline;
|
||||
payReq["timestamp"] = offer.contract.timestamp;
|
||||
payReq["transaction_id"] = offer.contract.transaction_id;
|
||||
@ -549,9 +549,9 @@ export class Wallet {
|
||||
confirmPay(offer: Offer): Promise<any> {
|
||||
console.log("executing confirmPay");
|
||||
return Promise.resolve().then(() => {
|
||||
return this.getPossibleMintCoins(offer.contract.amount,
|
||||
return this.getPossibleExchangeCoins(offer.contract.amount,
|
||||
offer.contract.max_fee,
|
||||
offer.contract.mints)
|
||||
offer.contract.exchanges)
|
||||
}).then((mcs) => {
|
||||
if (Object.keys(mcs).length == 0) {
|
||||
console.log("not confirming payment, insufficient coins");
|
||||
@ -559,10 +559,10 @@ export class Wallet {
|
||||
error: "coins-insufficient",
|
||||
};
|
||||
}
|
||||
let mintUrl = Object.keys(mcs)[0];
|
||||
let exchangeUrl = Object.keys(mcs)[0];
|
||||
|
||||
return this.cryptoApi.signDeposit(offer, mcs[mintUrl])
|
||||
.then((ds) => this.recordConfirmPay(offer, ds, mintUrl))
|
||||
return this.cryptoApi.signDeposit(offer, mcs[exchangeUrl])
|
||||
.then((ds) => this.recordConfirmPay(offer, ds, exchangeUrl))
|
||||
.then(() => ({}));
|
||||
});
|
||||
}
|
||||
@ -599,11 +599,11 @@ export class Wallet {
|
||||
* then deplete the reserve, withdrawing coins until it is empty.
|
||||
*/
|
||||
private initReserve(reserveRecord) {
|
||||
this.updateMintFromUrl(reserveRecord.mint_base_url)
|
||||
.then((mint) =>
|
||||
this.updateReserve(reserveRecord.reserve_pub, mint)
|
||||
this.updateExchangeFromUrl(reserveRecord.exchange_base_url)
|
||||
.then((exchange) =>
|
||||
this.updateReserve(reserveRecord.reserve_pub, exchange)
|
||||
.then((reserve) => this.depleteReserve(reserve,
|
||||
mint)))
|
||||
exchange)))
|
||||
.then(() => {
|
||||
let depleted = {
|
||||
type: "depleted-reserve",
|
||||
@ -627,12 +627,12 @@ export class Wallet {
|
||||
createReserve(req: CreateReserveRequest): Promise<CreateReserveResponse> {
|
||||
return this.cryptoApi.createEddsaKeypair().then((keypair) => {
|
||||
const now = (new Date).getTime();
|
||||
const canonMint = canonicalizeBaseUrl(req.mint);
|
||||
const canonExchange = canonicalizeBaseUrl(req.exchange);
|
||||
|
||||
const reserveRecord = {
|
||||
reserve_pub: keypair.pub,
|
||||
reserve_priv: keypair.priv,
|
||||
mint_base_url: canonMint,
|
||||
exchange_base_url: canonExchange,
|
||||
created: now,
|
||||
last_query: null,
|
||||
current_amount: null,
|
||||
@ -656,7 +656,7 @@ export class Wallet {
|
||||
.finish()
|
||||
.then(() => {
|
||||
let r: CreateReserveResponse = {
|
||||
mint: canonMint,
|
||||
exchange: canonExchange,
|
||||
reservePub: keypair.pub,
|
||||
};
|
||||
return r;
|
||||
@ -668,7 +668,7 @@ export class Wallet {
|
||||
/**
|
||||
* 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
|
||||
* since the exchange 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
|
||||
@ -708,7 +708,7 @@ export class Wallet {
|
||||
wd.reserve_pub = pc.reservePub;
|
||||
wd.reserve_sig = pc.withdrawSig;
|
||||
wd.coin_ev = pc.coinEv;
|
||||
let reqUrl = URI("reserve/withdraw").absoluteTo(r.mint_base_url);
|
||||
let reqUrl = URI("reserve/withdraw").absoluteTo(r.exchange_base_url);
|
||||
return this.http.postJson(reqUrl, wd);
|
||||
})
|
||||
.then(resp => {
|
||||
@ -727,7 +727,7 @@ export class Wallet {
|
||||
denomPub: pc.denomPub,
|
||||
denomSig: denomSig,
|
||||
currentAmount: pc.coinValue,
|
||||
mintBaseUrl: pc.mintBaseUrl,
|
||||
exchangeBaseUrl: pc.exchangeBaseUrl,
|
||||
};
|
||||
return coin;
|
||||
|
||||
@ -775,8 +775,8 @@ export class Wallet {
|
||||
/**
|
||||
* Withdraw coins from a reserve until it is empty.
|
||||
*/
|
||||
private depleteReserve(reserve, mint: MintInfo): Promise<void> {
|
||||
let denomsAvailable: Denomination[] = copy(mint.denoms);
|
||||
private depleteReserve(reserve, exchange: ExchangeInfo): Promise<void> {
|
||||
let denomsAvailable: Denomination[] = copy(exchange.denoms);
|
||||
let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount,
|
||||
denomsAvailable);
|
||||
|
||||
@ -793,13 +793,13 @@ export class Wallet {
|
||||
|
||||
/**
|
||||
* Update the information about a reserve that is stored in the wallet
|
||||
* by quering the reserve's mint.
|
||||
* by quering the reserve's exchange.
|
||||
*/
|
||||
private updateReserve(reservePub: string, mint: MintInfo): Promise<Reserve> {
|
||||
private updateReserve(reservePub: string, exchange: ExchangeInfo): Promise<Reserve> {
|
||||
return Query(this.db)
|
||||
.get("reserves", reservePub)
|
||||
.then((reserve) => {
|
||||
let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl);
|
||||
let reqUrl = URI("reserve/status").absoluteTo(exchange.baseUrl);
|
||||
reqUrl.query({'reserve_pub': reservePub});
|
||||
return this.http.get(reqUrl).then(resp => {
|
||||
if (resp.status != 200) {
|
||||
@ -832,10 +832,10 @@ export class Wallet {
|
||||
|
||||
getReserveCreationInfo(baseUrl: string,
|
||||
amount: AmountJson): Promise<ReserveCreationInfo> {
|
||||
return this.updateMintFromUrl(baseUrl)
|
||||
.then((mintInfo: IMintInfo) => {
|
||||
return this.updateExchangeFromUrl(baseUrl)
|
||||
.then((exchangeInfo: IExchangeInfo) => {
|
||||
let selectedDenoms = getWithdrawDenomList(amount,
|
||||
mintInfo.denoms);
|
||||
exchangeInfo.denoms);
|
||||
|
||||
let acc = Amounts.getZero(amount.currency);
|
||||
for (let d of selectedDenoms) {
|
||||
@ -846,7 +846,7 @@ export class Wallet {
|
||||
d.fee_withdraw).amount)
|
||||
.reduce((a, b) => Amounts.add(a, b).amount);
|
||||
let ret: ReserveCreationInfo = {
|
||||
mintInfo,
|
||||
exchangeInfo,
|
||||
selectedDenoms,
|
||||
withdrawFee: acc,
|
||||
overhead: Amounts.sub(amount, actualCoinCost).amount,
|
||||
@ -857,37 +857,37 @@ export class Wallet {
|
||||
|
||||
|
||||
/**
|
||||
* Update or add mint DB entry by fetching the /keys information.
|
||||
* Update or add exchange DB entry by fetching the /keys information.
|
||||
* Optionally link the reserve entry to the new or existing
|
||||
* mint entry in then DB.
|
||||
* exchange entry in then DB.
|
||||
*/
|
||||
updateMintFromUrl(baseUrl): Promise<MintInfo> {
|
||||
updateExchangeFromUrl(baseUrl): Promise<ExchangeInfo> {
|
||||
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||
let reqUrl = URI("keys").absoluteTo(baseUrl);
|
||||
return this.http.get(reqUrl).then((resp) => {
|
||||
if (resp.status != 200) {
|
||||
throw Error("/keys request failed");
|
||||
}
|
||||
let mintKeysJson = KeysJson.checked(JSON.parse(resp.responseText));
|
||||
let exchangeKeysJson = KeysJson.checked(JSON.parse(resp.responseText));
|
||||
|
||||
return Query(this.db).get("mints", baseUrl).then((r) => {
|
||||
let mintInfo;
|
||||
return Query(this.db).get("exchanges", baseUrl).then((r) => {
|
||||
let exchangeInfo;
|
||||
console.dir(r);
|
||||
|
||||
if (!r) {
|
||||
mintInfo = MintInfo.fresh(baseUrl);
|
||||
console.log("making fresh mint");
|
||||
exchangeInfo = ExchangeInfo.fresh(baseUrl);
|
||||
console.log("making fresh exchange");
|
||||
} else {
|
||||
mintInfo = new MintInfo(r);
|
||||
console.log("using old mint");
|
||||
exchangeInfo = new ExchangeInfo(r);
|
||||
console.log("using old exchange");
|
||||
}
|
||||
|
||||
return mintInfo.mergeKeys(mintKeysJson, this.cryptoApi)
|
||||
return exchangeInfo.mergeKeys(exchangeKeysJson, this.cryptoApi)
|
||||
.then(() => {
|
||||
return Query(this.db)
|
||||
.put("mints", mintInfo)
|
||||
.put("exchanges", exchangeInfo)
|
||||
.finish()
|
||||
.then(() => mintInfo);
|
||||
.then(() => exchangeInfo);
|
||||
});
|
||||
|
||||
});
|
||||
@ -954,4 +954,4 @@ export class Wallet {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ function makeHandlers(db: IDBDatabase,
|
||||
},
|
||||
["create-reserve"]: function(detail) {
|
||||
const d = {
|
||||
mint: detail.mint,
|
||||
exchange: detail.exchange,
|
||||
amount: detail.amount,
|
||||
};
|
||||
const req = CreateReserveRequest.checked(d);
|
||||
@ -96,11 +96,11 @@ function makeHandlers(db: IDBDatabase,
|
||||
["execute-payment"]: function(detail) {
|
||||
return wallet.executePayment(detail.H_contract);
|
||||
},
|
||||
["mint-info"]: function(detail) {
|
||||
["exchange-info"]: function(detail) {
|
||||
if (!detail.baseUrl) {
|
||||
return Promise.resolve({error: "bad url"});
|
||||
}
|
||||
return wallet.updateMintFromUrl(detail.baseUrl);
|
||||
return wallet.updateExchangeFromUrl(detail.baseUrl);
|
||||
},
|
||||
["reserve-creation-info"]: function(detail) {
|
||||
if (!detail.baseUrl || typeof detail.baseUrl !== "string") {
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<section id="main">
|
||||
<article>
|
||||
<div class="fade" id="mint-selection"></div>
|
||||
<div class="fade" id="exchange-selection"></div>
|
||||
</article>
|
||||
</section>
|
||||
</body>
|
||||
|
@ -19,7 +19,7 @@
|
||||
import {amountToPretty, canonicalizeBaseUrl} from "../lib/wallet/helpers";
|
||||
import {AmountJson, CreateReserveResponse} from "../lib/wallet/types";
|
||||
import m from "mithril";
|
||||
import {IMintInfo} from "../lib/wallet/types";
|
||||
import {IExchangeInfo} from "../lib/wallet/types";
|
||||
import {ReserveCreationInfo, Amounts} from "../lib/wallet/types";
|
||||
import MithrilComponent = _mithril.MithrilComponent;
|
||||
import {Denomination} from "../lib/wallet/types";
|
||||
@ -60,7 +60,7 @@ class DelayTimer {
|
||||
class Controller {
|
||||
url = m.prop<string>();
|
||||
statusString = null;
|
||||
isValidMint = false;
|
||||
isValidExchange = false;
|
||||
reserveCreationInfo: ReserveCreationInfo = null;
|
||||
private timer: DelayTimer;
|
||||
private request: XMLHttpRequest;
|
||||
@ -68,12 +68,12 @@ class Controller {
|
||||
callbackUrl: string;
|
||||
detailCollapsed = m.prop<boolean>(true);
|
||||
|
||||
constructor(initialMintUrl: string, amount: AmountJson, callbackUrl: string) {
|
||||
constructor(initialExchangeUrl: string, amount: AmountJson, callbackUrl: string) {
|
||||
console.log("creating main controller");
|
||||
this.amount = amount;
|
||||
this.callbackUrl = callbackUrl;
|
||||
this.timer = new DelayTimer(800, () => this.update());
|
||||
this.url(initialMintUrl);
|
||||
this.url(initialExchangeUrl);
|
||||
this.update();
|
||||
}
|
||||
|
||||
@ -93,19 +93,19 @@ class Controller {
|
||||
|
||||
m.redraw(true);
|
||||
|
||||
console.log("doing get mint info");
|
||||
console.log("doing get exchange info");
|
||||
|
||||
getReserveCreationInfo(this.url(), this.amount)
|
||||
.then((r: ReserveCreationInfo) => {
|
||||
console.log("get mint info resolved");
|
||||
this.isValidMint = true;
|
||||
console.log("get exchange info resolved");
|
||||
this.isValidExchange = true;
|
||||
this.reserveCreationInfo = r;
|
||||
console.dir(r);
|
||||
this.statusString = "The mint base URL is valid!";
|
||||
this.statusString = "The exchange base URL is valid!";
|
||||
m.endComputation();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("get mint info rejected");
|
||||
console.log("get exchange info rejected");
|
||||
if (e.hasOwnProperty("httpStatus")) {
|
||||
this.statusString = `request failed with status ${this.request.status}`;
|
||||
} else {
|
||||
@ -122,7 +122,7 @@ class Controller {
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.isValidMint = false;
|
||||
this.isValidExchange = false;
|
||||
this.statusString = null;
|
||||
this.reserveCreationInfo = null;
|
||||
if (this.request) {
|
||||
@ -131,8 +131,8 @@ class Controller {
|
||||
}
|
||||
}
|
||||
|
||||
confirmReserve(mint: string, amount: AmountJson, callback_url: string) {
|
||||
const d = {mint, amount};
|
||||
confirmReserve(exchange: string, amount: AmountJson, callback_url: string) {
|
||||
const d = {exchange, amount};
|
||||
const cb = (rawResp) => {
|
||||
if (!rawResp) {
|
||||
throw Error("empty response");
|
||||
@ -140,7 +140,7 @@ class Controller {
|
||||
if (!rawResp.error) {
|
||||
const resp = CreateReserveResponse.checked(rawResp);
|
||||
let q = {
|
||||
mint: resp.mint,
|
||||
exchange: resp.exchange,
|
||||
reserve_pub: resp.reservePub,
|
||||
amount_value: amount.value,
|
||||
amount_fraction: amount.fraction,
|
||||
@ -190,7 +190,7 @@ function view(ctrl: Controller) {
|
||||
onclick: () => ctrl.confirmReserve(ctrl.url(),
|
||||
ctrl.amount,
|
||||
ctrl.callbackUrl),
|
||||
disabled: !ctrl.isValidMint
|
||||
disabled: !ctrl.isValidExchange
|
||||
},
|
||||
"Confirm exchange selection");
|
||||
|
||||
@ -256,30 +256,30 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo) {
|
||||
}
|
||||
|
||||
|
||||
interface MintProbeResult {
|
||||
interface ExchangeProbeResult {
|
||||
keyInfo?: any;
|
||||
}
|
||||
|
||||
function probeMint(mintBaseUrl: string): Promise<MintProbeResult> {
|
||||
function probeExchange(exchangeBaseUrl: string): Promise<ExchangeProbeResult> {
|
||||
throw Error("not implemented");
|
||||
}
|
||||
|
||||
|
||||
function getSuggestedMint(currency: string): Promise<string> {
|
||||
function getSuggestedExchange(currency: string): Promise<string> {
|
||||
// TODO: make this request go to the wallet backend
|
||||
// Right now, this is a stub.
|
||||
const defaultMint = {
|
||||
const defaultExchange = {
|
||||
"KUDOS": "http://exchange.demo.taler.net",
|
||||
"PUDOS": "http://exchange.test.taler.net",
|
||||
};
|
||||
|
||||
let mint = defaultMint[currency];
|
||||
let exchange = defaultExchange[currency];
|
||||
|
||||
if (!mint) {
|
||||
mint = ""
|
||||
if (!exchange) {
|
||||
exchange = ""
|
||||
}
|
||||
|
||||
return Promise.resolve(mint);
|
||||
return Promise.resolve(exchange);
|
||||
}
|
||||
|
||||
|
||||
@ -290,11 +290,11 @@ export function main() {
|
||||
const callback_url = query.callback_url;
|
||||
const bank_url = query.bank_url;
|
||||
|
||||
getSuggestedMint(amount.currency)
|
||||
.then((suggestedMintUrl) => {
|
||||
const controller = () => new Controller(suggestedMintUrl, amount, callback_url);
|
||||
var MintSelection = {controller, view};
|
||||
m.mount(document.getElementById("mint-selection"), MintSelection);
|
||||
getSuggestedExchange(amount.currency)
|
||||
.then((suggestedExchangeUrl) => {
|
||||
const controller = () => new Controller(suggestedExchangeUrl, amount, callback_url);
|
||||
var ExchangeSelection = {controller, view};
|
||||
m.mount(document.getElementById("exchange-selection"), ExchangeSelection);
|
||||
})
|
||||
.catch((e) => {
|
||||
// TODO: provide more context information, maybe factor it out into a
|
||||
|
Loading…
Reference in New Issue
Block a user