diff options
| -rw-r--r-- | lib/wallet/wallet.ts | 22 | ||||
| -rw-r--r-- | lib/wallet/wxMessaging.ts | 18 | ||||
| -rw-r--r-- | pages/confirm-contract.html | 20 | ||||
| -rw-r--r-- | pages/confirm-contract.tsx | 30 | ||||
| -rw-r--r-- | pages/confirm-create-reserve.html | 11 | ||||
| -rw-r--r-- | pages/confirm-create-reserve.tsx | 18 | 
6 files changed, 114 insertions, 5 deletions
diff --git a/lib/wallet/wallet.ts b/lib/wallet/wallet.ts index dde7a8248..3c9f3ffed 100644 --- a/lib/wallet/wallet.ts +++ b/lib/wallet/wallet.ts @@ -522,6 +522,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.     */ diff --git a/lib/wallet/wxMessaging.ts b/lib/wallet/wxMessaging.ts index 64b16de8d..164342f4e 100644 --- a/lib/wallet/wxMessaging.ts +++ b/lib/wallet/wxMessaging.ts @@ -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);      }, diff --git a/pages/confirm-contract.html b/pages/confirm-contract.html index 54d02f316..ec7eab8c1 100644 --- a/pages/confirm-contract.html +++ b/pages/confirm-contract.html @@ -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> diff --git a/pages/confirm-contract.tsx b/pages/confirm-contract.tsx index 9e15841e9..2e055d4f1 100644 --- a/pages/confirm-contract.tsx +++ b/pages/confirm-contract.tsx @@ -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) => { diff --git a/pages/confirm-create-reserve.html b/pages/confirm-create-reserve.html index da87faf7f..32a29b9f7 100644 --- a/pages/confirm-create-reserve.html +++ b/pages/confirm-create-reserve.html @@ -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> diff --git a/pages/confirm-create-reserve.tsx b/pages/confirm-create-reserve.tsx index 4b4e19363..2c959429f 100644 --- a/pages/confirm-create-reserve.tsx +++ b/pages/confirm-create-reserve.tsx @@ -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)      ])    ];  }  | 
