This commit is contained in:
Florian Dold 2016-04-27 06:03:04 +02:00
parent b8ac91dbf9
commit d0a4f9f934
6 changed files with 114 additions and 5 deletions

View File

@ -521,6 +521,28 @@ export class Wallet {
}
/**
* Add a contract to the wallet and sign coins,
* but do not send them yet.
*/
checkPay(offer: Offer): Promise<any> {
console.log("executing checkPay");
return Promise.resolve().then(() => {
return this.getPossibleExchangeCoins(offer.contract.amount,
offer.contract.max_fee,
offer.contract.exchanges)
}).then((mcs) => {
if (Object.keys(mcs).length == 0) {
console.log("not confirming payment, insufficient coins");
return {
error: "coins-insufficient",
};
}
return {};
});
}
/**
* Retrieve all necessary information for looking up the contract
* with the given hash.

View File

@ -99,6 +99,24 @@ function makeHandlers(db: IDBDatabase,
return wallet.confirmPay(offer);
},
["check-pay"]: function(detail, sender) {
let offer;
try {
offer = Offer.checked(detail.offer);
} catch (e) {
if (e instanceof Checkable.SchemaError) {
console.error("schema error:", e.message);
return Promise.resolve({
error: "invalid contract",
hint: e.message,
detail: detail
});
} else {
throw e;
}
}
return wallet.checkPay(offer);
},
["execute-payment"]: function(detail, sender) {
return wallet.executePayment(detail.H_contract);
},

View File

@ -47,6 +47,26 @@
input.url {
width: 25em;
}
button.accept:disabled {
background-color: #dedbe8;
border: 1px solid white;
border-radius: 5px;
margin: 1em 0;
padding: 0.5em;
font-weight: bold;
color: #2C2C2C;
}
.errorbox {
border: 1px solid;
display: inline-block;
margin: 1em;
padding: 1em;
font-weight: bold;
background: #FF8A8A;
}
</style>
</head>

View File

@ -72,6 +72,7 @@ export function main() {
console.dir(offer);
let contract = offer.contract;
let error = null;
let payDisabled = true;
var Contract = {
view(ctrl) {
@ -87,8 +88,8 @@ export function main() {
_.map(contract.products,
(p: any) => m("li",
`${p.description}: ${prettyAmount(p.price)}`))),
m("button.accept", {onclick: doPayment}, i18n`Confirm Payment`),
m("p", error ? error : []),
m("button.accept", {onclick: doPayment, disabled: payDisabled}, i18n`Confirm Payment`),
(error ? m("p.errorbox", error) : []),
m(Details, contract)
];
}
@ -96,6 +97,31 @@ export function main() {
m.mount(document.getElementById("contract"), Contract);
function checkPayment() {
chrome.runtime.sendMessage({type: 'check-pay', detail: {offer}}, (resp) => {
if (resp.error) {
console.log("check-pay error", JSON.stringify(resp));
switch (resp.error) {
case "coins-insufficient":
error = "You do not have enough coins of the requested currency.";
break;
default:
error = `Error: ${resp.error}`;
break;
}
payDisabled = true;
} else {
payDisabled = false;
error = null;
}
m.redraw();
window.setTimeout(checkPayment, 300);
});
}
checkPayment();
function doPayment() {
let d = {offer};
chrome.runtime.sendMessage({type: 'confirm-pay', detail: d}, (resp) => {

View File

@ -45,6 +45,17 @@
width: 25em;
}
table {
border-collapse: collapse;
}
td {
border-left: 1px solid black;
border-right: 1px solid black;
text-align: center;
padding: 0.3em;
}
</style>
</head>

View File

@ -250,9 +250,21 @@ function view(ctrl: Controller) {
function renderReserveCreationDetails(rci: ReserveCreationInfo) {
let denoms = rci.selectedDenoms;
let countByPub = {};
let uniq = [];
denoms.forEach((x: Denomination) => {
let c = countByPub[x.denom_pub] || 0;
if (c == 0) {
uniq.push(x);
}
c += 1;
countByPub[x.denom_pub] = c;
});
function row(denom: Denomination) {
return m("tr", [
m("td", denom.pub_hash.substr(0, 5) + "..."),
m("td", countByPub[denom.denom_pub] + "x"),
m("td", amountToPretty(denom.value)),
m("td", amountToPretty(denom.fee_withdraw)),
m("td", amountToPretty(denom.fee_refresh)),
@ -267,13 +279,13 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo) {
m("p", `Overhead: ${overheadStr}`),
m("table", [
m("tr", [
m("th", "Key Hash"),
m("th", "Count"),
m("th", "Value"),
m("th", "Withdraw Fee"),
m("th", "Refresh Fee"),
m("th", "Deposit Fee"),
]),
denoms.map(row)
uniq.map(row)
])
];
}