From b2128609ac8159a14224deba399144b3400c8c20 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 13 Nov 2016 08:16:12 +0100 Subject: Finally give in and use React, minor tweeks. Preact (a minimalistic React alternative) had too many bugs ... --- lib/wallet/emscriptif.ts | 271 +++++++++++++++++++++++----------------------- lib/wallet/helpers.ts | 71 ++++++++++++ lib/wallet/http.ts | 13 +++ lib/wallet/renderHtml.tsx | 2 +- lib/wallet/wallet.ts | 125 +++++++-------------- lib/wallet/wxApi.ts | 2 +- 6 files changed, 257 insertions(+), 227 deletions(-) (limited to 'lib/wallet') diff --git a/lib/wallet/emscriptif.ts b/lib/wallet/emscriptif.ts index 3ae2db72a..4757fd8f4 100644 --- a/lib/wallet/emscriptif.ts +++ b/lib/wallet/emscriptif.ts @@ -35,157 +35,154 @@ const GNUNET_NO = 0; const GNUNET_SYSERR = -1; -function myCcall(name: string, ret: any, argTypes: any[], args: any[]) { - return Module.ccall(name, ret, argTypes, args); -} - -let getEmsc: EmscFunGen = (name: string, ret: any, - argTypes: any[]) => { +const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => { return (...args: any[]) => { - return myCcall(name, ret, argTypes, args); + return Module.ccall(name, ret, argTypes, args); } }; -var emsc = { +/** + * Wrapped emscripten functions that do not allocate any memory. + */ +const emsc = { free: (ptr: number) => Module._free(ptr), - get_value: getEmsc('TALER_WR_get_value', - 'number', - ['number']), - get_fraction: getEmsc('TALER_WR_get_fraction', - 'number', - ['number']), - get_currency: getEmsc('TALER_WR_get_currency', - 'string', - ['number']), - amount_add: getEmsc('TALER_amount_add', - 'number', - ['number', 'number', 'number']), - amount_subtract: getEmsc('TALER_amount_subtract', - 'number', - ['number', 'number', 'number']), - amount_normalize: getEmsc('TALER_amount_normalize', - 'void', - ['number']), - amount_get_zero: getEmsc('TALER_amount_get_zero', - 'number', - ['string', 'number']), - amount_cmp: getEmsc('TALER_amount_cmp', - 'number', - ['number', 'number']), - amount_hton: getEmsc('TALER_amount_hton', - 'void', - ['number', 'number']), - amount_ntoh: getEmsc('TALER_amount_ntoh', - 'void', - ['number', 'number']), - hash: getEmsc('GNUNET_CRYPTO_hash', - 'void', - ['number', 'number', 'number']), - memmove: getEmsc('memmove', - 'number', - ['number', 'number', 'number']), - rsa_public_key_free: getEmsc('GNUNET_CRYPTO_rsa_public_key_free', - 'void', - ['number']), - rsa_signature_free: getEmsc('GNUNET_CRYPTO_rsa_signature_free', - 'void', - ['number']), - string_to_data: getEmsc('GNUNET_STRINGS_string_to_data', - 'number', - ['number', 'number', 'number', 'number']), - eddsa_sign: getEmsc('GNUNET_CRYPTO_eddsa_sign', - 'number', - ['number', 'number', 'number']), - eddsa_verify: getEmsc('GNUNET_CRYPTO_eddsa_verify', - 'number', - ['number', 'number', 'number', 'number']), - hash_create_random: getEmsc('GNUNET_CRYPTO_hash_create_random', - 'void', - ['number', 'number']), - rsa_blinding_key_destroy: getEmsc('GNUNET_CRYPTO_rsa_blinding_key_free', - 'void', - ['number']), - random_block: getEmsc('GNUNET_CRYPTO_random_block', - 'void', - ['number', 'number', 'number']), - hash_context_abort: getEmsc('GNUNET_CRYPTO_hash_context_abort', - 'void', - ['number']), - hash_context_read: getEmsc('GNUNET_CRYPTO_hash_context_read', - 'void', - ['number', 'number', 'number']), - hash_context_finish: getEmsc('GNUNET_CRYPTO_hash_context_finish', - 'void', - ['number', 'number']), - ecdh_eddsa: getEmsc( - "GNUNET_CRYPTO_ecdh_eddsa", - 'number', - ["number", "number", "number"]), + get_value: getEmsc("TALER_WR_get_value", + "number", + ["number"]), + get_fraction: getEmsc("TALER_WR_get_fraction", + "number", + ["number"]), + get_currency: getEmsc("TALER_WR_get_currency", + "string", + ["number"]), + amount_add: getEmsc("TALER_amount_add", + "number", + ["number", "number", "number"]), + amount_subtract: getEmsc("TALER_amount_subtract", + "number", + ["number", "number", "number"]), + amount_normalize: getEmsc("TALER_amount_normalize", + "void", + ["number"]), + amount_get_zero: getEmsc("TALER_amount_get_zero", + "number", + ["string", "number"]), + amount_cmp: getEmsc("TALER_amount_cmp", + "number", + ["number", "number"]), + amount_hton: getEmsc("TALER_amount_hton", + "void", + ["number", "number"]), + amount_ntoh: getEmsc("TALER_amount_ntoh", + "void", + ["number", "number"]), + hash: getEmsc("GNUNET_CRYPTO_hash", + "void", + ["number", "number", "number"]), + memmove: getEmsc("memmove", + "number", + ["number", "number", "number"]), + rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free", + "void", + ["number"]), + rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free", + "void", + ["number"]), + string_to_data: getEmsc("GNUNET_STRINGS_string_to_data", + "number", + ["number", "number", "number", "number"]), + eddsa_sign: getEmsc("GNUNET_CRYPTO_eddsa_sign", + "number", + ["number", "number", "number"]), + eddsa_verify: getEmsc("GNUNET_CRYPTO_eddsa_verify", + "number", + ["number", "number", "number", "number"]), + hash_create_random: getEmsc("GNUNET_CRYPTO_hash_create_random", + "void", + ["number", "number"]), + rsa_blinding_key_destroy: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free", + "void", + ["number"]), + random_block: getEmsc("GNUNET_CRYPTO_random_block", + "void", + ["number", "number", "number"]), + hash_context_abort: getEmsc("GNUNET_CRYPTO_hash_context_abort", + "void", + ["number"]), + hash_context_read: getEmsc("GNUNET_CRYPTO_hash_context_read", + "void", + ["number", "number", "number"]), + hash_context_finish: getEmsc("GNUNET_CRYPTO_hash_context_finish", + "void", + ["number", "number"]), + ecdh_eddsa: getEmsc("GNUNET_CRYPTO_ecdh_eddsa", + "number", + ["number", "number", "number"]), setup_fresh_coin: getEmsc( "TALER_setup_fresh_coin", - 'void', + "void", ["number", "number", "number"]), }; -var emscAlloc = { - get_amount: getEmsc('TALER_WRALL_get_amount', - 'number', - ['number', 'number', 'number', 'string']), - eddsa_key_create: getEmsc('GNUNET_CRYPTO_eddsa_key_create', - 'number', []), - ecdsa_key_create: getEmsc('GNUNET_CRYPTO_ecdsa_key_create', - 'number', []), - ecdhe_key_create: getEmsc('GNUNET_CRYPTO_ecdhe_key_create', - 'number', []), +const emscAlloc = { + get_amount: getEmsc("TALER_WRALL_get_amount", + "number", + ["number", "number", "number", "string"]), + eddsa_key_create: getEmsc("GNUNET_CRYPTO_eddsa_key_create", + "number", []), + ecdsa_key_create: getEmsc("GNUNET_CRYPTO_ecdsa_key_create", + "number", []), + ecdhe_key_create: getEmsc("GNUNET_CRYPTO_ecdhe_key_create", + "number", []), eddsa_public_key_from_private: getEmsc( - 'TALER_WRALL_eddsa_public_key_from_private', - 'number', - ['number']), + "TALER_WRALL_eddsa_public_key_from_private", + "number", + ["number"]), ecdsa_public_key_from_private: getEmsc( - 'TALER_WRALL_ecdsa_public_key_from_private', - 'number', - ['number']), + "TALER_WRALL_ecdsa_public_key_from_private", + "number", + ["number"]), ecdhe_public_key_from_private: getEmsc( - 'TALER_WRALL_ecdhe_public_key_from_private', - 'number', - ['number']), - data_to_string_alloc: getEmsc('GNUNET_STRINGS_data_to_string_alloc', - 'number', - ['number', 'number']), - purpose_create: getEmsc('TALER_WRALL_purpose_create', - 'number', - ['number', 'number', 'number']), - rsa_blind: getEmsc('GNUNET_CRYPTO_rsa_blind', - 'number', - ['number', 'number', 'number', 'number', 'number']), - rsa_blinding_key_create: getEmsc('GNUNET_CRYPTO_rsa_blinding_key_create', - 'number', - ['number']), - rsa_blinding_key_encode: getEmsc('GNUNET_CRYPTO_rsa_blinding_key_encode', - 'number', - ['number', 'number']), - rsa_signature_encode: getEmsc('GNUNET_CRYPTO_rsa_signature_encode', - 'number', - ['number', 'number']), - rsa_blinding_key_decode: getEmsc('GNUNET_CRYPTO_rsa_blinding_key_decode', - 'number', - ['number', 'number']), - rsa_public_key_decode: getEmsc('GNUNET_CRYPTO_rsa_public_key_decode', - 'number', - ['number', 'number']), - rsa_signature_decode: getEmsc('GNUNET_CRYPTO_rsa_signature_decode', - 'number', - ['number', 'number']), - rsa_public_key_encode: getEmsc('GNUNET_CRYPTO_rsa_public_key_encode', - 'number', - ['number', 'number']), - rsa_unblind: getEmsc('GNUNET_CRYPTO_rsa_unblind', - 'number', - ['number', 'number', 'number']), - hash_context_start: getEmsc('GNUNET_CRYPTO_hash_context_start', - 'number', + "TALER_WRALL_ecdhe_public_key_from_private", + "number", + ["number"]), + data_to_string_alloc: getEmsc("GNUNET_STRINGS_data_to_string_alloc", + "number", + ["number", "number"]), + purpose_create: getEmsc("TALER_WRALL_purpose_create", + "number", + ["number", "number", "number"]), + rsa_blind: getEmsc("GNUNET_CRYPTO_rsa_blind", + "number", + ["number", "number", "number", "number", "number"]), + rsa_blinding_key_create: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_create", + "number", + ["number"]), + rsa_blinding_key_encode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_encode", + "number", + ["number", "number"]), + rsa_signature_encode: getEmsc("GNUNET_CRYPTO_rsa_signature_encode", + "number", + ["number", "number"]), + rsa_blinding_key_decode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_decode", + "number", + ["number", "number"]), + rsa_public_key_decode: getEmsc("GNUNET_CRYPTO_rsa_public_key_decode", + "number", + ["number", "number"]), + rsa_signature_decode: getEmsc("GNUNET_CRYPTO_rsa_signature_decode", + "number", + ["number", "number"]), + rsa_public_key_encode: getEmsc("GNUNET_CRYPTO_rsa_public_key_encode", + "number", + ["number", "number"]), + rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind", + "number", + ["number", "number", "number"]), + hash_context_start: getEmsc("GNUNET_CRYPTO_hash_context_start", + "number", []), malloc: (size: number) => Module._malloc(size), }; @@ -198,7 +195,7 @@ export enum SignaturePurpose { WALLET_COIN_MELT = 1202, } -enum RandomQuality { +export enum RandomQuality { WEAK = 0, STRONG = 1, NONCE = 2 diff --git a/lib/wallet/helpers.ts b/lib/wallet/helpers.ts index 8f65517f7..26cd350ee 100644 --- a/lib/wallet/helpers.ts +++ b/lib/wallet/helpers.ts @@ -67,3 +67,74 @@ export function parsePrettyAmount(pretty: string): AmountJson|undefined { currency: res[3] } } + + + +/** + * Convert object to JSON with canonical ordering of keys + * and whitespace omitted. + */ +export function canonicalJson(obj: any): string { + // Check for cycles, etc. + JSON.stringify(obj); + if (typeof obj == "string" || typeof obj == "number" || obj === null) { + return JSON.stringify(obj) + } + if (Array.isArray(obj)) { + let objs: string[] = obj.map((e) => canonicalJson(e)); + return `[${objs.join(',')}]`; + } + let keys: string[] = []; + for (let key in obj) { + keys.push(key); + } + keys.sort(); + let s = "{"; + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + s += JSON.stringify(key) + ":" + canonicalJson(obj[key]); + if (i != keys.length - 1) { + s += ","; + } + } + return s + "}"; +} + + +export function deepEquals(x: any, y: any): boolean { + if (x === y) { + return true; + } + + if (Array.isArray(x) && x.length !== y.length) { + return false; + } + + var p = Object.keys(x); + return Object.keys(y).every((i) => p.indexOf(i) !== -1) && + p.every((i) => deepEquals(x[i], y[i])); +} + + +export function flatMap(xs: T[], f: (x: T) => U[]): U[] { + return xs.reduce((acc: U[], next: T) => [...f(next), ...acc], []); +} + + +export function getTalerStampSec(stamp: string): number | null { + const m = stamp.match(/\/?Date\(([0-9]*)\)\/?/); + if (!m) { + return null; + } + return parseInt(m[1]); +} + + +export function getTalerStampDate(stamp: string): Date | null { + let sec = getTalerStampSec(stamp); + if (sec == null) { + return null; + } + return new Date(sec * 1000); +} + diff --git a/lib/wallet/http.ts b/lib/wallet/http.ts index 8f82ceaff..1d22c4eb2 100644 --- a/lib/wallet/http.ts +++ b/lib/wallet/http.ts @@ -29,6 +29,19 @@ export interface HttpResponse { } +export interface HttpRequestLibrary { + req(method: string, + url: string | uri.URI, + options?: any): Promise; + + get(url: string | uri.URI): Promise; + + postJson(url: string | uri.URI, body: any): Promise; + + postForm(url: string | uri.URI, form: any): Promise; +} + + export class BrowserHttpLib { req(method: string, url: string|uri.URI, diff --git a/lib/wallet/renderHtml.tsx b/lib/wallet/renderHtml.tsx index 52c01cd09..6afe32b74 100644 --- a/lib/wallet/renderHtml.tsx +++ b/lib/wallet/renderHtml.tsx @@ -60,4 +60,4 @@ export function abbrev(s: string, n: number = 5) { {sAbbrev} ); -} \ No newline at end of file +} diff --git a/lib/wallet/wallet.ts b/lib/wallet/wallet.ts index 7080a358b..47d42132d 100644 --- a/lib/wallet/wallet.ts +++ b/lib/wallet/wallet.ts @@ -23,25 +23,47 @@ import { AmountJson, + Amounts, + CheckRepurchaseResult, + Coin, + CoinPaySig, + Contract, CreateReserveResponse, - IExchangeInfo, Denomination, + ExchangeHandle, + IExchangeInfo, Notifier, - WireInfo, RefreshSession, ReserveRecord, CoinPaySig, WalletBalance, - WalletBalanceEntry + PayCoinInfo, + PreCoin, + RefreshSession, + ReserveCreationInfo, + ReserveRecord, + WalletBalance, + WalletBalanceEntry, + WireInfo, } from "./types"; -import {HttpResponse, RequestException} from "./http"; -import {QueryRoot, Store, Index, JoinResult, AbortTransaction} from "./query"; +import { + HttpRequestLibrary, + HttpResponse, + RequestException, +} from "./http"; +import { + AbortTransaction, + Index, + JoinResult, + QueryRoot, + Store, +} from "./query"; import {Checkable} from "./checkable"; -import {canonicalizeBaseUrl, amountToPretty} from "./helpers"; -import {ReserveCreationInfo, Amounts} from "./types"; -import {PreCoin} from "./types"; +import { + amountToPretty, + canonicalizeBaseUrl, + canonicalJson, + deepEquals, + flatMap, + getTalerStampSec, +} from "./helpers"; import {CryptoApi} from "./cryptoApi"; -import {Coin} from "./types"; -import {PayCoinInfo} from "./types"; -import {CheckRepurchaseResult} from "./types"; -import {Contract} from "./types"; -import {ExchangeHandle} from "./types"; "use strict"; @@ -182,61 +204,6 @@ export interface Badge { stopBusy(): void; } -export function canonicalJson(obj: any): string { - // Check for cycles, etc. - JSON.stringify(obj); - if (typeof obj == "string" || typeof obj == "number" || obj === null) { - return JSON.stringify(obj) - } - if (Array.isArray(obj)) { - let objs: string[] = obj.map((e) => canonicalJson(e)); - return `[${objs.join(',')}]`; - } - let keys: string[] = []; - for (let key in obj) { - keys.push(key); - } - keys.sort(); - let s = "{"; - for (let i = 0; i < keys.length; i++) { - let key = keys[i]; - s += JSON.stringify(key) + ":" + canonicalJson(obj[key]); - if (i != keys.length - 1) { - s += ","; - } - } - return s + "}"; -} - - -function deepEquals(x: any, y: any): boolean { - if (x === y) { - return true; - } - - if (Array.isArray(x) && x.length !== y.length) { - return false; - } - - var p = Object.keys(x); - return Object.keys(y).every((i) => p.indexOf(i) !== -1) && - p.every((i) => deepEquals(x[i], y[i])); -} - - -function flatMap(xs: T[], f: (x: T) => U[]): U[] { - return xs.reduce((acc: U[], next: T) => [...f(next), ...acc], []); -} - - -function getTalerStampSec(stamp: string): number | null { - const m = stamp.match(/\/?Date\(([0-9]*)\)\/?/); - if (!m) { - return null; - } - return parseInt(m[1]); -} - function setTimeout(f: any, t: number) { return chrome.extension.getBackgroundPage().setTimeout(f, t); @@ -255,23 +222,6 @@ function isWithdrawableDenom(d: Denomination) { } -interface HttpRequestLibrary { - req(method: string, - url: string | uri.URI, - options?: any): Promise; - - get(url: string | uri.URI): Promise; - - postJson(url: string | uri.URI, body: any): Promise; - - postForm(url: string | uri.URI, form: any): Promise; -} - - -function copy(o: any) { - return JSON.parse(JSON.stringify(o)); -} - /** * Result of updating exisiting information * about an exchange with a new '/keys' response. @@ -956,7 +906,7 @@ export class Wallet { if (!reserve.current_amount) { throw Error("can't withdraw when amount is unknown"); } - let denomsAvailable: Denomination[] = copy(exchange.active_denoms); + let denomsAvailable: Denomination[] = Array.from(exchange.active_denoms); let denomsForWithdraw = getWithdrawDenomList(reserve.current_amount!, denomsAvailable); @@ -1603,8 +1553,7 @@ export class Wallet { .toArray(); } - - async hashContract(contract: any): Promise { + async hashContract(contract: Contract): Promise { return this.cryptoApi.hashString(canonicalJson(contract)); } diff --git a/lib/wallet/wxApi.ts b/lib/wallet/wxApi.ts index 9ed7aabd3..a85b56c28 100644 --- a/lib/wallet/wxApi.ts +++ b/lib/wallet/wxApi.ts @@ -72,4 +72,4 @@ export async function getPreCoins(exchangeBaseUrl: string): Promise { export async function refresh(coinPub: string): Promise { return await callBackend("refresh-coin", { coinPub }); -} \ No newline at end of file +} -- cgit v1.2.3