Leave sending the payment blob to the merchant.
This commit is contained in:
parent
3877ace7dd
commit
d5fc7ee42d
@ -90,6 +90,7 @@ namespace TalerNotify {
|
|||||||
callback_url: URI(e.detail.callback_url)
|
callback_url: URI(e.detail.callback_url)
|
||||||
.absoluteTo(document.location.href),
|
.absoluteTo(document.location.href),
|
||||||
bank_url: document.location.href,
|
bank_url: document.location.href,
|
||||||
|
wt_types: JSON.stringify(e.detail.wt_types),
|
||||||
};
|
};
|
||||||
let uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html"));
|
let uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html"));
|
||||||
document.location.href = uri.query(params).href();
|
document.location.href = uri.query(params).href();
|
||||||
@ -157,20 +158,17 @@ namespace TalerNotify {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Should be: taler-request-payment, taler-result-payment
|
||||||
|
|
||||||
addHandler('taler-execute-payment', function(e: CustomEvent) {
|
addHandler("taler-execute-contract", function(e: CustomEvent) {
|
||||||
console.log("got taler-execute-payment in content page");
|
console.log("got taler-execute-contract in content page");
|
||||||
if (!e.detail.pay_url) {
|
|
||||||
console.log("field 'pay_url' missing in taler-execute-payment event");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const payUrl = e.detail.pay_url;
|
|
||||||
const msg = {
|
const msg = {
|
||||||
type: "execute-payment",
|
type: "execute-payment",
|
||||||
detail: {
|
detail: {
|
||||||
H_contract: e.detail.H_contract,
|
H_contract: e.detail.H_contract,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.runtime.sendMessage(msg, (resp) => {
|
chrome.runtime.sendMessage(msg, (resp) => {
|
||||||
console.log("got resp");
|
console.log("got resp");
|
||||||
console.dir(resp);
|
console.dir(resp);
|
||||||
@ -190,25 +188,13 @@ namespace TalerNotify {
|
|||||||
throw Error("contract missing");
|
throw Error("contract missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Making request to ", payUrl);
|
let evt = new CustomEvent("taler-notify-payment", {
|
||||||
let r = new XMLHttpRequest();
|
detail: {
|
||||||
r.open('post', payUrl);
|
contract: resp.contract,
|
||||||
r.send(JSON.stringify(resp.payReq));
|
payment: resp.payReq,
|
||||||
r.onload = () => {
|
|
||||||
switch (r.status) {
|
|
||||||
case 200:
|
|
||||||
console.log("going to", contract.fulfillment_url);
|
|
||||||
// TODO: Is this the right thing? Does the reload
|
|
||||||
// TODO: override setting location.href?
|
|
||||||
window.location.href = subst(contract.fulfillment_url,
|
|
||||||
e.detail.H_contract);
|
|
||||||
window.location.reload(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log("Unexpected status code for $pay_url:", r.status);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
document.dispatchEvent(evt);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,13 @@ export interface IExchangeInfo {
|
|||||||
denoms: Denomination[];
|
denoms: Denomination[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WireInfo {
|
||||||
|
[type: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ReserveCreationInfo {
|
export interface ReserveCreationInfo {
|
||||||
exchangeInfo: IExchangeInfo;
|
exchangeInfo: IExchangeInfo;
|
||||||
|
wireInfo: WireInfo;
|
||||||
selectedDenoms: Denomination[];
|
selectedDenoms: Denomination[];
|
||||||
withdrawFee: AmountJson;
|
withdrawFee: AmountJson;
|
||||||
overhead: AmountJson;
|
overhead: AmountJson;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* @author Florian Dold
|
* @author Florian Dold
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AmountJson, CreateReserveResponse, IExchangeInfo, Denomination, Notifier} from "./types";
|
import {AmountJson, CreateReserveResponse, IExchangeInfo, Denomination, Notifier, WireInfo} from "./types";
|
||||||
import {HttpResponse, RequestException} from "./http";
|
import {HttpResponse, RequestException} from "./http";
|
||||||
import {Query} from "./query";
|
import {Query} from "./query";
|
||||||
import {Checkable} from "./checkable";
|
import {Checkable} from "./checkable";
|
||||||
@ -184,7 +184,6 @@ export class ConfirmReserveRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Checkable.Class
|
@Checkable.Class
|
||||||
export class Offer {
|
export class Offer {
|
||||||
@Checkable.Value(Contract)
|
@Checkable.Value(Contract)
|
||||||
@ -346,12 +345,15 @@ export class Wallet {
|
|||||||
* but only if the sum the coins' remaining value exceeds the payment amount.
|
* but only if the sum the coins' remaining value exceeds the payment amount.
|
||||||
*/
|
*/
|
||||||
private getPossibleExchangeCoins(paymentAmount: AmountJson,
|
private getPossibleExchangeCoins(paymentAmount: AmountJson,
|
||||||
depositFeeLimit: AmountJson,
|
depositFeeLimit: AmountJson,
|
||||||
allowedExchanges: ExchangeHandle[]): Promise<ExchangeCoins> {
|
allowedExchanges: ExchangeHandle[]): Promise<ExchangeCoins> {
|
||||||
// Mapping from exchange base URL to list of coins together with their
|
// Mapping from exchange base URL to list of coins together with their
|
||||||
// denomination
|
// denomination
|
||||||
let m: ExchangeCoins = {};
|
let m: ExchangeCoins = {};
|
||||||
|
|
||||||
|
let x: number
|
||||||
|
|
||||||
|
|
||||||
function storeExchangeCoin(mc, url) {
|
function storeExchangeCoin(mc, url) {
|
||||||
let exchange: IExchangeInfo = mc[0];
|
let exchange: IExchangeInfo = mc[0];
|
||||||
console.log("got coin for exchange", url);
|
console.log("got coin for exchange", url);
|
||||||
@ -501,8 +503,8 @@ export class Wallet {
|
|||||||
console.log("executing confirmPay");
|
console.log("executing confirmPay");
|
||||||
return Promise.resolve().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
return this.getPossibleExchangeCoins(offer.contract.amount,
|
return this.getPossibleExchangeCoins(offer.contract.amount,
|
||||||
offer.contract.max_fee,
|
offer.contract.max_fee,
|
||||||
offer.contract.exchanges)
|
offer.contract.exchanges)
|
||||||
}).then((mcs) => {
|
}).then((mcs) => {
|
||||||
if (Object.keys(mcs).length == 0) {
|
if (Object.keys(mcs).length == 0) {
|
||||||
console.log("not confirming payment, insufficient coins");
|
console.log("not confirming payment, insufficient coins");
|
||||||
@ -746,7 +748,8 @@ export class Wallet {
|
|||||||
* Update the information about a reserve that is stored in the wallet
|
* Update the information about a reserve that is stored in the wallet
|
||||||
* by quering the reserve's exchange.
|
* by quering the reserve's exchange.
|
||||||
*/
|
*/
|
||||||
private updateReserve(reservePub: string, exchange: ExchangeInfo): Promise<Reserve> {
|
private updateReserve(reservePub: string,
|
||||||
|
exchange: ExchangeInfo): Promise<Reserve> {
|
||||||
return Query(this.db)
|
return Query(this.db)
|
||||||
.get("reserves", reservePub)
|
.get("reserves", reservePub)
|
||||||
.then((reserve) => {
|
.then((reserve) => {
|
||||||
@ -781,29 +784,47 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getWireInfo(baseUrl: string): Promise<WireInfo> {
|
||||||
|
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
|
let reqUrl = URI("wire").absoluteTo(baseUrl);
|
||||||
|
return this.http.get(reqUrl).then((resp: HttpResponse) => {
|
||||||
|
if (resp.status != 200) {
|
||||||
|
throw Error("/wire request failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
let wiJson = JSON.parse(resp.responseText);
|
||||||
|
if (!wiJson) {
|
||||||
|
throw Error("/wire response malformed")
|
||||||
|
}
|
||||||
|
return wiJson;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getReserveCreationInfo(baseUrl: string,
|
getReserveCreationInfo(baseUrl: string,
|
||||||
amount: AmountJson): Promise<ReserveCreationInfo> {
|
amount: AmountJson): Promise<ReserveCreationInfo> {
|
||||||
return this.updateExchangeFromUrl(baseUrl)
|
let p = this.updateExchangeFromUrl(baseUrl);
|
||||||
.then((exchangeInfo: IExchangeInfo) => {
|
return p.then((exchangeInfo: IExchangeInfo) => {
|
||||||
let selectedDenoms = getWithdrawDenomList(amount,
|
let selectedDenoms = getWithdrawDenomList(amount, exchangeInfo.denoms);
|
||||||
exchangeInfo.denoms);
|
let acc = Amounts.getZero(amount.currency);
|
||||||
|
for (let d of selectedDenoms) {
|
||||||
|
acc = Amounts.add(acc, d.fee_withdraw).amount;
|
||||||
|
}
|
||||||
|
let actualCoinCost = selectedDenoms
|
||||||
|
.map((d: Denomination) => Amounts.add(d.value,
|
||||||
|
d.fee_withdraw).amount)
|
||||||
|
.reduce((a, b) => Amounts.add(a, b).amount);
|
||||||
|
return this.getWireInfo(baseUrl).then((wireInfo) => {
|
||||||
|
let ret: ReserveCreationInfo = {
|
||||||
|
exchangeInfo,
|
||||||
|
selectedDenoms,
|
||||||
|
wireInfo,
|
||||||
|
withdrawFee: acc,
|
||||||
|
overhead: Amounts.sub(amount, actualCoinCost).amount,
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
let acc = Amounts.getZero(amount.currency);
|
});
|
||||||
for (let d of selectedDenoms) {
|
|
||||||
acc = Amounts.add(acc, d.fee_withdraw).amount;
|
|
||||||
}
|
|
||||||
let actualCoinCost = selectedDenoms
|
|
||||||
.map((d: Denomination) => Amounts.add(d.value,
|
|
||||||
d.fee_withdraw).amount)
|
|
||||||
.reduce((a, b) => Amounts.add(a, b).amount);
|
|
||||||
let ret: ReserveCreationInfo = {
|
|
||||||
exchangeInfo,
|
|
||||||
selectedDenoms,
|
|
||||||
withdrawFee: acc,
|
|
||||||
overhead: Amounts.sub(amount, actualCoinCost).amount,
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -834,12 +855,12 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return exchangeInfo.mergeKeys(exchangeKeysJson, this.cryptoApi)
|
return exchangeInfo.mergeKeys(exchangeKeysJson, this.cryptoApi)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return Query(this.db)
|
return Query(this.db)
|
||||||
.put("exchanges", exchangeInfo)
|
.put("exchanges", exchangeInfo)
|
||||||
.finish()
|
.finish()
|
||||||
.then(() => exchangeInfo);
|
.then(() => exchangeInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -74,12 +74,17 @@ class Controller {
|
|||||||
private request: XMLHttpRequest;
|
private request: XMLHttpRequest;
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
callbackUrl: string;
|
callbackUrl: string;
|
||||||
|
wtTypes: string[];
|
||||||
detailCollapsed = m.prop<boolean>(true);
|
detailCollapsed = m.prop<boolean>(true);
|
||||||
|
|
||||||
constructor(initialExchangeUrl: string, amount: AmountJson, callbackUrl: string) {
|
constructor(initialExchangeUrl: string,
|
||||||
|
amount: AmountJson,
|
||||||
|
callbackUrl: string,
|
||||||
|
wt_types: string[]) {
|
||||||
console.log("creating main controller");
|
console.log("creating main controller");
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.callbackUrl = callbackUrl;
|
this.callbackUrl = callbackUrl;
|
||||||
|
this.wtTypes = wt_types;
|
||||||
this.timer = new DelayTimer(800, () => this.update());
|
this.timer = new DelayTimer(800, () => this.update());
|
||||||
this.url(initialExchangeUrl);
|
this.url(initialExchangeUrl);
|
||||||
this.update();
|
this.update();
|
||||||
@ -125,7 +130,6 @@ class Controller {
|
|||||||
|
|
||||||
doUpdate();
|
doUpdate();
|
||||||
|
|
||||||
|
|
||||||
console.log("got update");
|
console.log("got update");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,15 +143,21 @@ class Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmReserve(exchange: string, amount: AmountJson, callback_url: string) {
|
confirmReserve(rci: ReserveCreationInfo,
|
||||||
|
exchange: string,
|
||||||
|
amount: AmountJson,
|
||||||
|
callback_url: string) {
|
||||||
const d = {exchange, amount};
|
const d = {exchange, amount};
|
||||||
const cb = (rawResp) => {
|
const cb = (rawResp) => {
|
||||||
if (!rawResp) {
|
if (!rawResp) {
|
||||||
throw Error("empty response");
|
throw Error("empty response");
|
||||||
}
|
}
|
||||||
|
// FIXME: filter out types that bank/exchange don't have in common
|
||||||
|
let wire_details = rci.wireInfo;
|
||||||
if (!rawResp.error) {
|
if (!rawResp.error) {
|
||||||
const resp = CreateReserveResponse.checked(rawResp);
|
const resp = CreateReserveResponse.checked(rawResp);
|
||||||
let q = {
|
let q: {[name: string]: string|number} = {
|
||||||
|
wire_details: JSON.stringify(wire_details),
|
||||||
exchange: resp.exchange,
|
exchange: resp.exchange,
|
||||||
reserve_pub: resp.reservePub,
|
reserve_pub: resp.reservePub,
|
||||||
amount_value: amount.value,
|
amount_value: amount.value,
|
||||||
@ -195,7 +205,8 @@ function view(ctrl: Controller) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
mx("button", {
|
mx("button", {
|
||||||
onclick: () => ctrl.confirmReserve(ctrl.url(),
|
onclick: () => ctrl.confirmReserve(ctrl.reserveCreationInfo,
|
||||||
|
ctrl.url(),
|
||||||
ctrl.amount,
|
ctrl.amount,
|
||||||
ctrl.callbackUrl),
|
ctrl.callbackUrl),
|
||||||
disabled: !ctrl.isValidExchange
|
disabled: !ctrl.isValidExchange
|
||||||
@ -264,15 +275,6 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface ExchangeProbeResult {
|
|
||||||
keyInfo?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
function probeExchange(exchangeBaseUrl: string): Promise<ExchangeProbeResult> {
|
|
||||||
throw Error("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getSuggestedExchange(currency: string): Promise<string> {
|
function getSuggestedExchange(currency: string): Promise<string> {
|
||||||
// TODO: make this request go to the wallet backend
|
// TODO: make this request go to the wallet backend
|
||||||
// Right now, this is a stub.
|
// Right now, this is a stub.
|
||||||
@ -297,10 +299,11 @@ export function main() {
|
|||||||
const amount = AmountJson.checked(JSON.parse(query.amount));
|
const amount = AmountJson.checked(JSON.parse(query.amount));
|
||||||
const callback_url = query.callback_url;
|
const callback_url = query.callback_url;
|
||||||
const bank_url = query.bank_url;
|
const bank_url = query.bank_url;
|
||||||
|
const wt_types = JSON.parse(query.wt_types);
|
||||||
|
|
||||||
getSuggestedExchange(amount.currency)
|
getSuggestedExchange(amount.currency)
|
||||||
.then((suggestedExchangeUrl) => {
|
.then((suggestedExchangeUrl) => {
|
||||||
const controller = () => new Controller(suggestedExchangeUrl, amount, callback_url);
|
const controller = () => new Controller(suggestedExchangeUrl, amount, callback_url, wt_types);
|
||||||
var ExchangeSelection = {controller, view};
|
var ExchangeSelection = {controller, view};
|
||||||
m.mount(document.getElementById("exchange-selection"), ExchangeSelection);
|
m.mount(document.getElementById("exchange-selection"), ExchangeSelection);
|
||||||
})
|
})
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
<script src="../lib/vendor/lodash.core.min.js"></script>
|
<script src="../lib/vendor/lodash.core.min.js"></script>
|
||||||
<script src="../lib/vendor/system-csp-production.src.js"></script>
|
<script src="../lib/vendor/system-csp-production.src.js"></script>
|
||||||
<script src="../lib/vendor/jed.js"></script>
|
<script src="../lib/vendor/jed.js"></script>
|
||||||
|
<script src="../lib/i18n.js"></script>
|
||||||
<script src="../i18n/strings.js"></script>
|
<script src="../i18n/strings.js"></script>
|
||||||
<script src="../lib/i18n.js"></script>
|
|
||||||
<script src="../lib/module-trampoline.js"></script>
|
<script src="../lib/module-trampoline.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ namespace WalletBalance {
|
|||||||
{config: openInExtension},
|
{config: openInExtension},
|
||||||
i18n`help`);
|
i18n`help`);
|
||||||
|
|
||||||
return i18n.parts`You have no balance to show. Need some ${helpLink}? getting started?`;
|
return i18n.parts`You have no balance to show. Need some ${helpLink} getting started?`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user