diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-02-01 15:10:20 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-02-01 15:10:20 +0100 |
commit | 42a0076f5951d303635b2e544aa66112cdb9abfe (patch) | |
tree | 432874ec0e7dbe6c831992f70a468bc1b6719901 /extension/lib/wallet | |
parent | b150470eb60017b4ccdf56351428f9452a207fc8 (diff) | |
download | wallet-core-42a0076f5951d303635b2e544aa66112cdb9abfe.tar.xz |
new fulfillment protocol
Diffstat (limited to 'extension/lib/wallet')
-rw-r--r-- | extension/lib/wallet/checkable.ts | 136 | ||||
-rw-r--r-- | extension/lib/wallet/emscriptif.ts | 4 | ||||
-rw-r--r-- | extension/lib/wallet/query.ts | 2 | ||||
-rw-r--r-- | extension/lib/wallet/types.ts | 13 | ||||
-rw-r--r-- | extension/lib/wallet/wallet.ts | 85 | ||||
-rw-r--r-- | extension/lib/wallet/wxmessaging.js | 10 | ||||
-rw-r--r-- | extension/lib/wallet/wxmessaging.ts | 10 |
7 files changed, 56 insertions, 204 deletions
diff --git a/extension/lib/wallet/checkable.ts b/extension/lib/wallet/checkable.ts deleted file mode 100644 index 7587f529c..000000000 --- a/extension/lib/wallet/checkable.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - This file is part of TALER - (C) 2016 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> - */ - - -"use strict"; - -/** - * Decorators for type-checking JSON into - * an object. - * @module Checkable - * @author Florian Dold - */ - -export namespace Checkable { - let chkSym = Symbol("checkable"); - - function checkNumber(target, prop): any { - if ((typeof target) !== "number") { - throw Error("number expected for " + prop.propertyKey); - } - return target; - } - - function checkString(target, prop): any { - if (typeof target !== "string") { - throw Error("string expected for " + prop.propertyKey); - } - return target; - } - - function checkAnyObject(target, prop): any { - if (typeof target !== "object") { - throw Error("object expected for " + prop.propertyKey); - } - return target; - } - - function checkValue(target, prop): any { - let type = prop.type; - if (!type) { - throw Error("assertion failed"); - } - let v = target; - if (!v || typeof v !== "object") { - throw Error("expected object for " + prop.propertyKey); - } - let props = type.prototype[chkSym].props; - let remainingPropNames = new Set(Object.getOwnPropertyNames(v)); - let obj = new type(); - for (let prop of props) { - if (!remainingPropNames.has(prop.propertyKey)) { - throw Error("Property missing: " + prop.propertyKey); - } - if (!remainingPropNames.delete(prop.propertyKey)) { - throw Error("assertion failed"); - } - let propVal = v[prop.propertyKey]; - obj[prop.propertyKey] = prop.checker(propVal, prop); - } - - if (remainingPropNames.size != 0) { - throw Error("superfluous properties " + JSON.stringify(Array.from( - remainingPropNames.values()))); - } - return obj; - } - - export function Class(target) { - target.checked = (v) => { - return checkValue(v, { - propertyKey: "(root)", - type: target, - checker: checkValue - }); - }; - return target; - } - - export function Value(type) { - function deco(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({ - propertyKey: propertyKey, - checker: checkValue, - type: type - }); - } - - return deco; - } - - export function List(type) { - function deco(target: Object, propertyKey: string | symbol): void { - throw Error("not implemented"); - } - - return deco; - } - - export function Number(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({propertyKey: propertyKey, checker: checkNumber}); - } - - export function AnyObject(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({propertyKey: propertyKey, checker: checkAnyObject}); - } - - export function String(target: Object, propertyKey: string | symbol): void { - let chk = mkChk(target); - chk.props.push({propertyKey: propertyKey, checker: checkString}); - } - - function mkChk(target) { - let chk = target[chkSym]; - if (!chk) { - chk = {props: []}; - target[chkSym] = chk; - } - return chk; - } -} diff --git a/extension/lib/wallet/emscriptif.ts b/extension/lib/wallet/emscriptif.ts index 223fe7348..b11d845f0 100644 --- a/extension/lib/wallet/emscriptif.ts +++ b/extension/lib/wallet/emscriptif.ts @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> */ -import {AmountJson_interface} from "./types"; +import {AmountJson} from "./types"; import * as EmscWrapper from "../emscripten/emsc"; /** @@ -288,7 +288,7 @@ arenaStack.push(new SyncArena()); export class Amount extends ArenaObject { - constructor(args?: AmountJson_interface, arena?: Arena) { + constructor(args?: AmountJson, arena?: Arena) { super(arena); if (args) { this.nativePtr = emscAlloc.get_amount(args.value, diff --git a/extension/lib/wallet/query.ts b/extension/lib/wallet/query.ts index 375816193..82053138f 100644 --- a/extension/lib/wallet/query.ts +++ b/extension/lib/wallet/query.ts @@ -14,8 +14,6 @@ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> */ -/// <reference path="../decl/urijs/URIjs.d.ts" /> - /** * Database query abstractions. diff --git a/extension/lib/wallet/types.ts b/extension/lib/wallet/types.ts index 75233ff82..478287a21 100644 --- a/extension/lib/wallet/types.ts +++ b/extension/lib/wallet/types.ts @@ -33,10 +33,10 @@ export interface Keys { } export interface Denomination { - value: AmountJson_interface; + value: AmountJson; denom_pub: string; - fee_withdraw: AmountJson_interface; - fee_deposit: AmountJson_interface; + fee_withdraw: AmountJson; + fee_deposit: AmountJson; } export interface PreCoin { @@ -48,7 +48,7 @@ export interface PreCoin { withdrawSig: string; coinEv: string; mintBaseUrl: string; - coinValue: AmountJson_interface; + coinValue: AmountJson; } export interface Coin { @@ -56,17 +56,18 @@ export interface Coin { coinPriv: string; denomPub: string; denomSig: string; - currentAmount: AmountJson_interface; + currentAmount: AmountJson; mintBaseUrl: string; } -export interface AmountJson_interface { +export interface AmountJson { value: number; fraction: number currency: string; } + export interface ConfirmReserveRequest { /** * Name of the form field for the amount. diff --git a/extension/lib/wallet/wallet.ts b/extension/lib/wallet/wallet.ts index f8a322d58..cbc3e4b01 100644 --- a/extension/lib/wallet/wallet.ts +++ b/extension/lib/wallet/wallet.ts @@ -22,7 +22,6 @@ */ import {Amount} from "./emscriptif" -import {AmountJson_interface} from "./types"; import {CoinWithDenom} from "./types"; import {DepositRequestPS_Args} from "./emscriptif"; import {HashCode} from "./emscriptif"; @@ -45,46 +44,25 @@ import {PreCoin} from "./types"; import {rsaUnblind} from "./emscriptif"; import {RsaSignature} from "./emscriptif"; import {Mint} from "./types"; -import {Checkable} from "./checkable"; import {HttpResponse} from "./http"; import {RequestException} from "./http"; import {Query} from "./query"; +import {AmountJson} from "./types"; "use strict"; -@Checkable.Class -class AmountJson { - @Checkable.Number - value: number; - @Checkable.Number - fraction: number; - @Checkable.String - currency: string; - - static check: (v: any) => AmountJson; -} - - -@Checkable.Class class CoinPaySig { - @Checkable.String coin_sig: string; - @Checkable.String coin_pub: string; - @Checkable.String ub_sig: string; - @Checkable.String denom_pub: string; - @Checkable.Value(AmountJson) f: AmountJson; - - static check: (v: any) => CoinPaySig; } @@ -104,17 +82,17 @@ interface MintInfo { interface Offer { contract: Contract; - sig: string; + merchant_sig: string; H_contract: string; } interface Contract { H_wire: string; - amount: AmountJson_interface; + amount: AmountJson; auditors: string[]; expiry: string, locations: string[]; - max_fee: AmountJson_interface; + max_fee: AmountJson; merchant: any; merchant_pub: string; mints: MintInfo[]; @@ -122,6 +100,7 @@ interface Contract { refund_deadline: string; timestamp: string; transaction_id: number; + fulfillment_url: string; } @@ -130,7 +109,7 @@ interface CoinPaySig_interface { coin_pub: string; ub_sig: string; denom_pub: string; - f: AmountJson_interface; + f: AmountJson; } @@ -177,7 +156,7 @@ function canonicalizeBaseUrl(url) { return x.href() } -function parsePrettyAmount(pretty: string): AmountJson_interface { +function parsePrettyAmount(pretty: string): AmountJson { const res = /([0-9]+)(.[0-9]+)?\s*(\w+)/.exec(pretty); if (!res) { return null; @@ -291,8 +270,8 @@ export class Wallet { * @param depositFeeLimit * @param allowedMints */ - getPossibleMintCoins(paymentAmount: AmountJson_interface, - depositFeeLimit: AmountJson_interface, + getPossibleMintCoins(paymentAmount: AmountJson, + depositFeeLimit: AmountJson, allowedMints: MintInfo[]): Promise<MintCoins> { @@ -366,15 +345,17 @@ export class Wallet { executePay(offer: Offer, payCoinInfo: PayCoinInfo, - chosenMint: string): Promise<void> { + chosenMint: string): Promise<any> { let payReq = {}; - payReq["H_wire"] = offer.contract.H_wire; + payReq["amount"] = offer.contract.amount; + payReq["coins"] = payCoinInfo.map((x) => x.sig); payReq["H_contract"] = offer.H_contract; - payReq["transaction_id"] = offer.contract.transaction_id; - payReq["refund_deadline"] = offer.contract.refund_deadline; + payReq["max_fee"] = offer.contract.max_fee; + payReq["merchant_sig"] = offer.merchant_sig; payReq["mint"] = URI(chosenMint).href(); - payReq["coins"] = payCoinInfo.map((x) => x.sig); + payReq["refund_deadline"] = offer.contract.refund_deadline; payReq["timestamp"] = offer.contract.timestamp; + payReq["transaction_id"] = offer.contract.transaction_id; let t: Transaction = { contractHash: offer.H_contract, contract: offer.contract, @@ -387,7 +368,8 @@ export class Wallet { detail: { merchantName: offer.contract.merchant.name, amount: offer.contract.amount, - contractHash: offer.H_contract + contractHash: offer.H_contract, + fulfillmentUrl: offer.contract.fulfillment_url } }; @@ -395,7 +377,12 @@ export class Wallet { .put("transactions", t) .put("history", historyEntry) .putAll("coins", payCoinInfo.map((pci) => pci.updatedCoin)) - .finish(); + .finish() + .then(() => { + return { + success: true + }; + }); } confirmPay(offer: Offer): Promise<any> { @@ -405,23 +392,31 @@ export class Wallet { offer.contract.mints) }).then((mcs) => { if (Object.keys(mcs).length == 0) { - throw Error("Not enough coins."); + return { + success: false, + message: "Not enough coins", + }; } let mintUrl = Object.keys(mcs)[0]; let ds = Wallet.signDeposit(offer, mcs[mintUrl]); - return this.executePay(offer, ds, mintUrl); + return this + .executePay(offer, ds, mintUrl); }); } - doPayment(H_contract): Promise<PaymentResponse> { + doPayment(H_contract): Promise<any> { return Promise.resolve().then(() => { return Query(this.db) .get("transactions", H_contract) .then((t) => { if (!t) { - throw Error("contract not found"); + return { + success: false, + contractFound: false, + } } - let resp: PaymentResponse = { + let resp = { + success: true, payReq: t.payReq, contract: t.contract, }; @@ -682,8 +677,10 @@ export class Wallet { let next = () => { if (workList.length == 0) { resolve(); + return; } let d = workList.pop(); + console.log("withdrawing", JSON.stringify(d)); this.withdraw(d, reserve) .then(() => next()) .catch((e) => { @@ -760,7 +757,7 @@ export class Wallet { getBalances(): Promise<any> { function collectBalances(c: Coin, byCurrency) { - let acc: AmountJson_interface = byCurrency[c.currentAmount.currency]; + let acc: AmountJson = byCurrency[c.currentAmount.currency]; if (!acc) { acc = Amount.getZero(c.currentAmount.currency).toJson(); } @@ -786,4 +783,4 @@ export class Wallet { .iter("history", {indexName: "timestamp"}) .reduce(collect, []) } -} +}
\ No newline at end of file diff --git a/extension/lib/wallet/wxmessaging.js b/extension/lib/wallet/wxmessaging.js index ad49ca03a..bd108276f 100644 --- a/extension/lib/wallet/wxmessaging.js +++ b/extension/lib/wallet/wxmessaging.js @@ -66,8 +66,8 @@ System.register(["./wallet", "./db", "./http"], function(exports_1) { }, _a["confirm-pay"] = function (db, detail, sendResponse) { wallet.confirmPay(detail.offer, detail.merchantPageUrl) - .then(function () { - sendResponse({ success: true }); + .then(function (r) { + sendResponse(r); }) .catch(function (e) { console.error("exception during 'confirm-pay'"); @@ -79,11 +79,7 @@ System.register(["./wallet", "./db", "./http"], function(exports_1) { _a["execute-payment"] = function (db, detail, sendResponse) { wallet.doPayment(detail.H_contract) .then(function (r) { - sendResponse({ - success: true, - payReq: r.payReq, - contract: r.contract, - }); + sendResponse(r); }) .catch(function (e) { console.error("exception during 'execute-payment'"); diff --git a/extension/lib/wallet/wxmessaging.ts b/extension/lib/wallet/wxmessaging.ts index 0ec07dfe1..63310270f 100644 --- a/extension/lib/wallet/wxmessaging.ts +++ b/extension/lib/wallet/wxmessaging.ts @@ -83,8 +83,8 @@ function makeHandlers(wallet) { }, ["confirm-pay"]: function(db, detail, sendResponse) { wallet.confirmPay(detail.offer, detail.merchantPageUrl) - .then(() => { - sendResponse({success: true}) + .then((r) => { + sendResponse(r) }) .catch((e) => { console.error("exception during 'confirm-pay'"); @@ -96,11 +96,7 @@ function makeHandlers(wallet) { ["execute-payment"]: function(db, detail, sendResponse) { wallet.doPayment(detail.H_contract) .then((r) => { - sendResponse({ - success: true, - payReq: r.payReq, - contract: r.contract, - }); + sendResponse(r); }) .catch((e) => { console.error("exception during 'execute-payment'"); |