diff options
Diffstat (limited to 'src')
30 files changed, 504 insertions, 1772 deletions
diff --git a/src/crypto/primitives/nacl-fast.ts b/src/crypto/primitives/nacl-fast.ts index 1defe1ad0..8d4aaeb63 100644 --- a/src/crypto/primitives/nacl-fast.ts +++ b/src/crypto/primitives/nacl-fast.ts @@ -5,7 +5,7 @@  // Implementation derived from TweetNaCl version 20140427.  // See for details: http://tweetnacl.cr.yp.to/ -const gf = function (init: number[] = []) { +const gf = function (init: number[] = []): Float64Array {    const r = new Float64Array(16);    if (init) for (let i = 0; i < init.length; i++) r[i] = init[i];    return r; @@ -16,7 +16,6 @@ let randombytes = function (x: Uint8Array, n: number): void {    throw new Error("no PRNG");  }; -const _0 = new Uint8Array(16);  const _9 = new Uint8Array(32);  _9[0] = 9; @@ -115,7 +114,7 @@ const I = gf([    0x2b83,  ]); -function ts64(x: Uint8Array, i: number, h: number, l: number) { +function ts64(x: Uint8Array, i: number, h: number, l: number): void {    x[i] = (h >> 24) & 0xff;    x[i + 1] = (h >> 16) & 0xff;    x[i + 2] = (h >> 8) & 0xff; @@ -126,20 +125,17 @@ function ts64(x: Uint8Array, i: number, h: number, l: number) {    x[i + 7] = l & 0xff;  } -function vn(x: Uint8Array, xi: number, y: Uint8Array, yi: number, n: number) { -  let i, -    d = 0; -  for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; -  return (1 & ((d - 1) >>> 8)) - 1; -} - -function crypto_verify_16( +function vn(    x: Uint8Array,    xi: number,    y: Uint8Array,    yi: number, -) { -  return vn(x, xi, y, yi, 16); +  n: number, +): number { +  let i, +    d = 0; +  for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; +  return (1 & ((d - 1) >>> 8)) - 1;  }  function crypto_verify_32( @@ -147,1014 +143,16 @@ function crypto_verify_32(    xi: number,    y: Uint8Array,    yi: number, -) { +): number {    return vn(x, xi, y, yi, 32);  } -// prettier-ignore -function core_salsa20(o: Uint8Array, p: Uint8Array, k: Uint8Array, c: Uint8Array) { -  const j0  = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, -      j1  = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, -      j2  = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, -      j3  = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, -      j4  = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, -      j5  = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, -      j6  = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, -      j7  = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, -      j8  = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, -      j9  = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, -      j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, -      j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, -      j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, -      j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, -      j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, -      j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; - -  let x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, -      x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, -      x15 = j15, u; - -  for (let i = 0; i < 20; i += 2) { -    u = x0 + x12 | 0; -    x4 ^= u<<7 | u>>>(32-7); -    u = x4 + x0 | 0; -    x8 ^= u<<9 | u>>>(32-9); -    u = x8 + x4 | 0; -    x12 ^= u<<13 | u>>>(32-13); -    u = x12 + x8 | 0; -    x0 ^= u<<18 | u>>>(32-18); - -    u = x5 + x1 | 0; -    x9 ^= u<<7 | u>>>(32-7); -    u = x9 + x5 | 0; -    x13 ^= u<<9 | u>>>(32-9); -    u = x13 + x9 | 0; -    x1 ^= u<<13 | u>>>(32-13); -    u = x1 + x13 | 0; -    x5 ^= u<<18 | u>>>(32-18); - -    u = x10 + x6 | 0; -    x14 ^= u<<7 | u>>>(32-7); -    u = x14 + x10 | 0; -    x2 ^= u<<9 | u>>>(32-9); -    u = x2 + x14 | 0; -    x6 ^= u<<13 | u>>>(32-13); -    u = x6 + x2 | 0; -    x10 ^= u<<18 | u>>>(32-18); - -    u = x15 + x11 | 0; -    x3 ^= u<<7 | u>>>(32-7); -    u = x3 + x15 | 0; -    x7 ^= u<<9 | u>>>(32-9); -    u = x7 + x3 | 0; -    x11 ^= u<<13 | u>>>(32-13); -    u = x11 + x7 | 0; -    x15 ^= u<<18 | u>>>(32-18); - -    u = x0 + x3 | 0; -    x1 ^= u<<7 | u>>>(32-7); -    u = x1 + x0 | 0; -    x2 ^= u<<9 | u>>>(32-9); -    u = x2 + x1 | 0; -    x3 ^= u<<13 | u>>>(32-13); -    u = x3 + x2 | 0; -    x0 ^= u<<18 | u>>>(32-18); - -    u = x5 + x4 | 0; -    x6 ^= u<<7 | u>>>(32-7); -    u = x6 + x5 | 0; -    x7 ^= u<<9 | u>>>(32-9); -    u = x7 + x6 | 0; -    x4 ^= u<<13 | u>>>(32-13); -    u = x4 + x7 | 0; -    x5 ^= u<<18 | u>>>(32-18); - -    u = x10 + x9 | 0; -    x11 ^= u<<7 | u>>>(32-7); -    u = x11 + x10 | 0; -    x8 ^= u<<9 | u>>>(32-9); -    u = x8 + x11 | 0; -    x9 ^= u<<13 | u>>>(32-13); -    u = x9 + x8 | 0; -    x10 ^= u<<18 | u>>>(32-18); - -    u = x15 + x14 | 0; -    x12 ^= u<<7 | u>>>(32-7); -    u = x12 + x15 | 0; -    x13 ^= u<<9 | u>>>(32-9); -    u = x13 + x12 | 0; -    x14 ^= u<<13 | u>>>(32-13); -    u = x14 + x13 | 0; -    x15 ^= u<<18 | u>>>(32-18); -  } -   x0 =  x0 +  j0 | 0; -   x1 =  x1 +  j1 | 0; -   x2 =  x2 +  j2 | 0; -   x3 =  x3 +  j3 | 0; -   x4 =  x4 +  j4 | 0; -   x5 =  x5 +  j5 | 0; -   x6 =  x6 +  j6 | 0; -   x7 =  x7 +  j7 | 0; -   x8 =  x8 +  j8 | 0; -   x9 =  x9 +  j9 | 0; -  x10 = x10 + j10 | 0; -  x11 = x11 + j11 | 0; -  x12 = x12 + j12 | 0; -  x13 = x13 + j13 | 0; -  x14 = x14 + j14 | 0; -  x15 = x15 + j15 | 0; - -  o[ 0] = x0 >>>  0 & 0xff; -  o[ 1] = x0 >>>  8 & 0xff; -  o[ 2] = x0 >>> 16 & 0xff; -  o[ 3] = x0 >>> 24 & 0xff; - -  o[ 4] = x1 >>>  0 & 0xff; -  o[ 5] = x1 >>>  8 & 0xff; -  o[ 6] = x1 >>> 16 & 0xff; -  o[ 7] = x1 >>> 24 & 0xff; - -  o[ 8] = x2 >>>  0 & 0xff; -  o[ 9] = x2 >>>  8 & 0xff; -  o[10] = x2 >>> 16 & 0xff; -  o[11] = x2 >>> 24 & 0xff; - -  o[12] = x3 >>>  0 & 0xff; -  o[13] = x3 >>>  8 & 0xff; -  o[14] = x3 >>> 16 & 0xff; -  o[15] = x3 >>> 24 & 0xff; - -  o[16] = x4 >>>  0 & 0xff; -  o[17] = x4 >>>  8 & 0xff; -  o[18] = x4 >>> 16 & 0xff; -  o[19] = x4 >>> 24 & 0xff; - -  o[20] = x5 >>>  0 & 0xff; -  o[21] = x5 >>>  8 & 0xff; -  o[22] = x5 >>> 16 & 0xff; -  o[23] = x5 >>> 24 & 0xff; - -  o[24] = x6 >>>  0 & 0xff; -  o[25] = x6 >>>  8 & 0xff; -  o[26] = x6 >>> 16 & 0xff; -  o[27] = x6 >>> 24 & 0xff; - -  o[28] = x7 >>>  0 & 0xff; -  o[29] = x7 >>>  8 & 0xff; -  o[30] = x7 >>> 16 & 0xff; -  o[31] = x7 >>> 24 & 0xff; - -  o[32] = x8 >>>  0 & 0xff; -  o[33] = x8 >>>  8 & 0xff; -  o[34] = x8 >>> 16 & 0xff; -  o[35] = x8 >>> 24 & 0xff; - -  o[36] = x9 >>>  0 & 0xff; -  o[37] = x9 >>>  8 & 0xff; -  o[38] = x9 >>> 16 & 0xff; -  o[39] = x9 >>> 24 & 0xff; - -  o[40] = x10 >>>  0 & 0xff; -  o[41] = x10 >>>  8 & 0xff; -  o[42] = x10 >>> 16 & 0xff; -  o[43] = x10 >>> 24 & 0xff; - -  o[44] = x11 >>>  0 & 0xff; -  o[45] = x11 >>>  8 & 0xff; -  o[46] = x11 >>> 16 & 0xff; -  o[47] = x11 >>> 24 & 0xff; - -  o[48] = x12 >>>  0 & 0xff; -  o[49] = x12 >>>  8 & 0xff; -  o[50] = x12 >>> 16 & 0xff; -  o[51] = x12 >>> 24 & 0xff; - -  o[52] = x13 >>>  0 & 0xff; -  o[53] = x13 >>>  8 & 0xff; -  o[54] = x13 >>> 16 & 0xff; -  o[55] = x13 >>> 24 & 0xff; - -  o[56] = x14 >>>  0 & 0xff; -  o[57] = x14 >>>  8 & 0xff; -  o[58] = x14 >>> 16 & 0xff; -  o[59] = x14 >>> 24 & 0xff; - -  o[60] = x15 >>>  0 & 0xff; -  o[61] = x15 >>>  8 & 0xff; -  o[62] = x15 >>> 16 & 0xff; -  o[63] = x15 >>> 24 & 0xff; -} - -function core_hsalsa20( -  o: Uint8Array, -  p: Uint8Array, -  k: Uint8Array, -  c: Uint8Array, -) { -  const j0 = -      (c[0] & 0xff) | -      ((c[1] & 0xff) << 8) | -      ((c[2] & 0xff) << 16) | -      ((c[3] & 0xff) << 24), -    j1 = -      (k[0] & 0xff) | -      ((k[1] & 0xff) << 8) | -      ((k[2] & 0xff) << 16) | -      ((k[3] & 0xff) << 24), -    j2 = -      (k[4] & 0xff) | -      ((k[5] & 0xff) << 8) | -      ((k[6] & 0xff) << 16) | -      ((k[7] & 0xff) << 24), -    j3 = -      (k[8] & 0xff) | -      ((k[9] & 0xff) << 8) | -      ((k[10] & 0xff) << 16) | -      ((k[11] & 0xff) << 24), -    j4 = -      (k[12] & 0xff) | -      ((k[13] & 0xff) << 8) | -      ((k[14] & 0xff) << 16) | -      ((k[15] & 0xff) << 24), -    j5 = -      (c[4] & 0xff) | -      ((c[5] & 0xff) << 8) | -      ((c[6] & 0xff) << 16) | -      ((c[7] & 0xff) << 24), -    j6 = -      (p[0] & 0xff) | -      ((p[1] & 0xff) << 8) | -      ((p[2] & 0xff) << 16) | -      ((p[3] & 0xff) << 24), -    j7 = -      (p[4] & 0xff) | -      ((p[5] & 0xff) << 8) | -      ((p[6] & 0xff) << 16) | -      ((p[7] & 0xff) << 24), -    j8 = -      (p[8] & 0xff) | -      ((p[9] & 0xff) << 8) | -      ((p[10] & 0xff) << 16) | -      ((p[11] & 0xff) << 24), -    j9 = -      (p[12] & 0xff) | -      ((p[13] & 0xff) << 8) | -      ((p[14] & 0xff) << 16) | -      ((p[15] & 0xff) << 24), -    j10 = -      (c[8] & 0xff) | -      ((c[9] & 0xff) << 8) | -      ((c[10] & 0xff) << 16) | -      ((c[11] & 0xff) << 24), -    j11 = -      (k[16] & 0xff) | -      ((k[17] & 0xff) << 8) | -      ((k[18] & 0xff) << 16) | -      ((k[19] & 0xff) << 24), -    j12 = -      (k[20] & 0xff) | -      ((k[21] & 0xff) << 8) | -      ((k[22] & 0xff) << 16) | -      ((k[23] & 0xff) << 24), -    j13 = -      (k[24] & 0xff) | -      ((k[25] & 0xff) << 8) | -      ((k[26] & 0xff) << 16) | -      ((k[27] & 0xff) << 24), -    j14 = -      (k[28] & 0xff) | -      ((k[29] & 0xff) << 8) | -      ((k[30] & 0xff) << 16) | -      ((k[31] & 0xff) << 24), -    j15 = -      (c[12] & 0xff) | -      ((c[13] & 0xff) << 8) | -      ((c[14] & 0xff) << 16) | -      ((c[15] & 0xff) << 24); - -  let x0 = j0, -    x1 = j1, -    x2 = j2, -    x3 = j3, -    x4 = j4, -    x5 = j5, -    x6 = j6, -    x7 = j7, -    x8 = j8, -    x9 = j9, -    x10 = j10, -    x11 = j11, -    x12 = j12, -    x13 = j13, -    x14 = j14, -    x15 = j15, -    u; - -  for (let i = 0; i < 20; i += 2) { -    u = (x0 + x12) | 0; -    x4 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x4 + x0) | 0; -    x8 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x8 + x4) | 0; -    x12 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x12 + x8) | 0; -    x0 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x5 + x1) | 0; -    x9 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x9 + x5) | 0; -    x13 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x13 + x9) | 0; -    x1 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x1 + x13) | 0; -    x5 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x10 + x6) | 0; -    x14 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x14 + x10) | 0; -    x2 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x2 + x14) | 0; -    x6 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x6 + x2) | 0; -    x10 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x15 + x11) | 0; -    x3 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x3 + x15) | 0; -    x7 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x7 + x3) | 0; -    x11 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x11 + x7) | 0; -    x15 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x0 + x3) | 0; -    x1 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x1 + x0) | 0; -    x2 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x2 + x1) | 0; -    x3 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x3 + x2) | 0; -    x0 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x5 + x4) | 0; -    x6 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x6 + x5) | 0; -    x7 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x7 + x6) | 0; -    x4 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x4 + x7) | 0; -    x5 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x10 + x9) | 0; -    x11 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x11 + x10) | 0; -    x8 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x8 + x11) | 0; -    x9 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x9 + x8) | 0; -    x10 ^= (u << 18) | (u >>> (32 - 18)); - -    u = (x15 + x14) | 0; -    x12 ^= (u << 7) | (u >>> (32 - 7)); -    u = (x12 + x15) | 0; -    x13 ^= (u << 9) | (u >>> (32 - 9)); -    u = (x13 + x12) | 0; -    x14 ^= (u << 13) | (u >>> (32 - 13)); -    u = (x14 + x13) | 0; -    x15 ^= (u << 18) | (u >>> (32 - 18)); -  } - -  o[0] = (x0 >>> 0) & 0xff; -  o[1] = (x0 >>> 8) & 0xff; -  o[2] = (x0 >>> 16) & 0xff; -  o[3] = (x0 >>> 24) & 0xff; - -  o[4] = (x5 >>> 0) & 0xff; -  o[5] = (x5 >>> 8) & 0xff; -  o[6] = (x5 >>> 16) & 0xff; -  o[7] = (x5 >>> 24) & 0xff; - -  o[8] = (x10 >>> 0) & 0xff; -  o[9] = (x10 >>> 8) & 0xff; -  o[10] = (x10 >>> 16) & 0xff; -  o[11] = (x10 >>> 24) & 0xff; - -  o[12] = (x15 >>> 0) & 0xff; -  o[13] = (x15 >>> 8) & 0xff; -  o[14] = (x15 >>> 16) & 0xff; -  o[15] = (x15 >>> 24) & 0xff; - -  o[16] = (x6 >>> 0) & 0xff; -  o[17] = (x6 >>> 8) & 0xff; -  o[18] = (x6 >>> 16) & 0xff; -  o[19] = (x6 >>> 24) & 0xff; - -  o[20] = (x7 >>> 0) & 0xff; -  o[21] = (x7 >>> 8) & 0xff; -  o[22] = (x7 >>> 16) & 0xff; -  o[23] = (x7 >>> 24) & 0xff; - -  o[24] = (x8 >>> 0) & 0xff; -  o[25] = (x8 >>> 8) & 0xff; -  o[26] = (x8 >>> 16) & 0xff; -  o[27] = (x8 >>> 24) & 0xff; - -  o[28] = (x9 >>> 0) & 0xff; -  o[29] = (x9 >>> 8) & 0xff; -  o[30] = (x9 >>> 16) & 0xff; -  o[31] = (x9 >>> 24) & 0xff; -} - -function crypto_core_salsa20( -  out: Uint8Array, -  inp: Uint8Array, -  k: Uint8Array, -  c: Uint8Array, -) { -  core_salsa20(out, inp, k, c); -} - -function crypto_core_hsalsa20( -  out: Uint8Array, -  inp: Uint8Array, -  k: Uint8Array, -  c: Uint8Array, -) { -  core_hsalsa20(out, inp, k, c); -} - -const sigma = new Uint8Array([ -  101, -  120, -  112, -  97, -  110, -  100, -  32, -  51, -  50, -  45, -  98, -  121, -  116, -  101, -  32, -  107, -]); -// "expand 32-byte k" - -function crypto_stream_salsa20_xor( -  c: Uint8Array, -  cpos: number, -  m: Uint8Array, -  mpos: number, -  b: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  const z = new Uint8Array(16), -    x = new Uint8Array(64); -  let u, i; -  for (i = 0; i < 16; i++) z[i] = 0; -  for (i = 0; i < 8; i++) z[i] = n[i]; -  while (b >= 64) { -    crypto_core_salsa20(x, z, k, sigma); -    for (i = 0; i < 64; i++) c[cpos + i] = m[mpos + i] ^ x[i]; -    u = 1; -    for (i = 8; i < 16; i++) { -      u = (u + (z[i] & 0xff)) | 0; -      z[i] = u & 0xff; -      u >>>= 8; -    } -    b -= 64; -    cpos += 64; -    mpos += 64; -  } -  if (b > 0) { -    crypto_core_salsa20(x, z, k, sigma); -    for (i = 0; i < b; i++) c[cpos + i] = m[mpos + i] ^ x[i]; -  } -  return 0; -} - -function crypto_stream_salsa20( -  c: Uint8Array, -  cpos: number, -  b: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  const z = new Uint8Array(16), -    x = new Uint8Array(64); -  let u, i; -  for (i = 0; i < 16; i++) z[i] = 0; -  for (i = 0; i < 8; i++) z[i] = n[i]; -  while (b >= 64) { -    crypto_core_salsa20(x, z, k, sigma); -    for (i = 0; i < 64; i++) c[cpos + i] = x[i]; -    u = 1; -    for (i = 8; i < 16; i++) { -      u = (u + (z[i] & 0xff)) | 0; -      z[i] = u & 0xff; -      u >>>= 8; -    } -    b -= 64; -    cpos += 64; -  } -  if (b > 0) { -    crypto_core_salsa20(x, z, k, sigma); -    for (i = 0; i < b; i++) c[cpos + i] = x[i]; -  } -  return 0; -} - -function crypto_stream( -  c: Uint8Array, -  cpos: number, -  d: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  const s = new Uint8Array(32); -  crypto_core_hsalsa20(s, n, k, sigma); -  const sn = new Uint8Array(8); -  for (let i = 0; i < 8; i++) sn[i] = n[i + 16]; -  return crypto_stream_salsa20(c, cpos, d, sn, s); -} - -function crypto_stream_xor( -  c: Uint8Array, -  cpos: number, -  m: Uint8Array, -  mpos: number, -  d: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  const s = new Uint8Array(32); -  crypto_core_hsalsa20(s, n, k, sigma); -  const sn = new Uint8Array(8); -  for (let i = 0; i < 8; i++) sn[i] = n[i + 16]; -  return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s); -} - -/* - * Port of Andrew Moon's Poly1305-donna-16. Public domain. - * https://github.com/floodyberry/poly1305-donna - */ - -class poly1305 { -  buffer = new Uint8Array(16); -  r = new Uint16Array(10); -  h = new Uint16Array(10); -  pad = new Uint16Array(8); -  leftover = 0; -  fin = 0; - -  constructor(key: Uint8Array) { -    let t0, t1, t2, t3, t4, t5, t6, t7; - -    t0 = (key[0] & 0xff) | ((key[1] & 0xff) << 8); -    this.r[0] = t0 & 0x1fff; -    t1 = (key[2] & 0xff) | ((key[3] & 0xff) << 8); -    this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; -    t2 = (key[4] & 0xff) | ((key[5] & 0xff) << 8); -    this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; -    t3 = (key[6] & 0xff) | ((key[7] & 0xff) << 8); -    this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; -    t4 = (key[8] & 0xff) | ((key[9] & 0xff) << 8); -    this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; -    this.r[5] = (t4 >>> 1) & 0x1ffe; -    t5 = (key[10] & 0xff) | ((key[11] & 0xff) << 8); -    this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; -    t6 = (key[12] & 0xff) | ((key[13] & 0xff) << 8); -    this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; -    t7 = (key[14] & 0xff) | ((key[15] & 0xff) << 8); -    this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; -    this.r[9] = (t7 >>> 5) & 0x007f; - -    this.pad[0] = (key[16] & 0xff) | ((key[17] & 0xff) << 8); -    this.pad[1] = (key[18] & 0xff) | ((key[19] & 0xff) << 8); -    this.pad[2] = (key[20] & 0xff) | ((key[21] & 0xff) << 8); -    this.pad[3] = (key[22] & 0xff) | ((key[23] & 0xff) << 8); -    this.pad[4] = (key[24] & 0xff) | ((key[25] & 0xff) << 8); -    this.pad[5] = (key[26] & 0xff) | ((key[27] & 0xff) << 8); -    this.pad[6] = (key[28] & 0xff) | ((key[29] & 0xff) << 8); -    this.pad[7] = (key[30] & 0xff) | ((key[31] & 0xff) << 8); -  } - -  blocks(m: Uint8Array, mpos: number, bytes: number) { -    const hibit = this.fin ? 0 : 1 << 11; -    let t0, t1, t2, t3, t4, t5, t6, t7, c; -    let d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; - -    let h0 = this.h[0], -      h1 = this.h[1], -      h2 = this.h[2], -      h3 = this.h[3], -      h4 = this.h[4], -      h5 = this.h[5], -      h6 = this.h[6], -      h7 = this.h[7], -      h8 = this.h[8], -      h9 = this.h[9]; - -    const r0 = this.r[0], -      r1 = this.r[1], -      r2 = this.r[2], -      r3 = this.r[3], -      r4 = this.r[4], -      r5 = this.r[5], -      r6 = this.r[6], -      r7 = this.r[7], -      r8 = this.r[8], -      r9 = this.r[9]; - -    while (bytes >= 16) { -      t0 = (m[mpos + 0] & 0xff) | ((m[mpos + 1] & 0xff) << 8); -      h0 += t0 & 0x1fff; -      t1 = (m[mpos + 2] & 0xff) | ((m[mpos + 3] & 0xff) << 8); -      h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; -      t2 = (m[mpos + 4] & 0xff) | ((m[mpos + 5] & 0xff) << 8); -      h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; -      t3 = (m[mpos + 6] & 0xff) | ((m[mpos + 7] & 0xff) << 8); -      h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; -      t4 = (m[mpos + 8] & 0xff) | ((m[mpos + 9] & 0xff) << 8); -      h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; -      h5 += (t4 >>> 1) & 0x1fff; -      t5 = (m[mpos + 10] & 0xff) | ((m[mpos + 11] & 0xff) << 8); -      h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; -      t6 = (m[mpos + 12] & 0xff) | ((m[mpos + 13] & 0xff) << 8); -      h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; -      t7 = (m[mpos + 14] & 0xff) | ((m[mpos + 15] & 0xff) << 8); -      h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; -      h9 += (t7 >>> 5) | hibit; - -      c = 0; - -      d0 = c; -      d0 += h0 * r0; -      d0 += h1 * (5 * r9); -      d0 += h2 * (5 * r8); -      d0 += h3 * (5 * r7); -      d0 += h4 * (5 * r6); -      c = d0 >>> 13; -      d0 &= 0x1fff; -      d0 += h5 * (5 * r5); -      d0 += h6 * (5 * r4); -      d0 += h7 * (5 * r3); -      d0 += h8 * (5 * r2); -      d0 += h9 * (5 * r1); -      c += d0 >>> 13; -      d0 &= 0x1fff; - -      d1 = c; -      d1 += h0 * r1; -      d1 += h1 * r0; -      d1 += h2 * (5 * r9); -      d1 += h3 * (5 * r8); -      d1 += h4 * (5 * r7); -      c = d1 >>> 13; -      d1 &= 0x1fff; -      d1 += h5 * (5 * r6); -      d1 += h6 * (5 * r5); -      d1 += h7 * (5 * r4); -      d1 += h8 * (5 * r3); -      d1 += h9 * (5 * r2); -      c += d1 >>> 13; -      d1 &= 0x1fff; - -      d2 = c; -      d2 += h0 * r2; -      d2 += h1 * r1; -      d2 += h2 * r0; -      d2 += h3 * (5 * r9); -      d2 += h4 * (5 * r8); -      c = d2 >>> 13; -      d2 &= 0x1fff; -      d2 += h5 * (5 * r7); -      d2 += h6 * (5 * r6); -      d2 += h7 * (5 * r5); -      d2 += h8 * (5 * r4); -      d2 += h9 * (5 * r3); -      c += d2 >>> 13; -      d2 &= 0x1fff; - -      d3 = c; -      d3 += h0 * r3; -      d3 += h1 * r2; -      d3 += h2 * r1; -      d3 += h3 * r0; -      d3 += h4 * (5 * r9); -      c = d3 >>> 13; -      d3 &= 0x1fff; -      d3 += h5 * (5 * r8); -      d3 += h6 * (5 * r7); -      d3 += h7 * (5 * r6); -      d3 += h8 * (5 * r5); -      d3 += h9 * (5 * r4); -      c += d3 >>> 13; -      d3 &= 0x1fff; - -      d4 = c; -      d4 += h0 * r4; -      d4 += h1 * r3; -      d4 += h2 * r2; -      d4 += h3 * r1; -      d4 += h4 * r0; -      c = d4 >>> 13; -      d4 &= 0x1fff; -      d4 += h5 * (5 * r9); -      d4 += h6 * (5 * r8); -      d4 += h7 * (5 * r7); -      d4 += h8 * (5 * r6); -      d4 += h9 * (5 * r5); -      c += d4 >>> 13; -      d4 &= 0x1fff; - -      d5 = c; -      d5 += h0 * r5; -      d5 += h1 * r4; -      d5 += h2 * r3; -      d5 += h3 * r2; -      d5 += h4 * r1; -      c = d5 >>> 13; -      d5 &= 0x1fff; -      d5 += h5 * r0; -      d5 += h6 * (5 * r9); -      d5 += h7 * (5 * r8); -      d5 += h8 * (5 * r7); -      d5 += h9 * (5 * r6); -      c += d5 >>> 13; -      d5 &= 0x1fff; - -      d6 = c; -      d6 += h0 * r6; -      d6 += h1 * r5; -      d6 += h2 * r4; -      d6 += h3 * r3; -      d6 += h4 * r2; -      c = d6 >>> 13; -      d6 &= 0x1fff; -      d6 += h5 * r1; -      d6 += h6 * r0; -      d6 += h7 * (5 * r9); -      d6 += h8 * (5 * r8); -      d6 += h9 * (5 * r7); -      c += d6 >>> 13; -      d6 &= 0x1fff; - -      d7 = c; -      d7 += h0 * r7; -      d7 += h1 * r6; -      d7 += h2 * r5; -      d7 += h3 * r4; -      d7 += h4 * r3; -      c = d7 >>> 13; -      d7 &= 0x1fff; -      d7 += h5 * r2; -      d7 += h6 * r1; -      d7 += h7 * r0; -      d7 += h8 * (5 * r9); -      d7 += h9 * (5 * r8); -      c += d7 >>> 13; -      d7 &= 0x1fff; - -      d8 = c; -      d8 += h0 * r8; -      d8 += h1 * r7; -      d8 += h2 * r6; -      d8 += h3 * r5; -      d8 += h4 * r4; -      c = d8 >>> 13; -      d8 &= 0x1fff; -      d8 += h5 * r3; -      d8 += h6 * r2; -      d8 += h7 * r1; -      d8 += h8 * r0; -      d8 += h9 * (5 * r9); -      c += d8 >>> 13; -      d8 &= 0x1fff; - -      d9 = c; -      d9 += h0 * r9; -      d9 += h1 * r8; -      d9 += h2 * r7; -      d9 += h3 * r6; -      d9 += h4 * r5; -      c = d9 >>> 13; -      d9 &= 0x1fff; -      d9 += h5 * r4; -      d9 += h6 * r3; -      d9 += h7 * r2; -      d9 += h8 * r1; -      d9 += h9 * r0; -      c += d9 >>> 13; -      d9 &= 0x1fff; - -      c = ((c << 2) + c) | 0; -      c = (c + d0) | 0; -      d0 = c & 0x1fff; -      c = c >>> 13; -      d1 += c; - -      h0 = d0; -      h1 = d1; -      h2 = d2; -      h3 = d3; -      h4 = d4; -      h5 = d5; -      h6 = d6; -      h7 = d7; -      h8 = d8; -      h9 = d9; - -      mpos += 16; -      bytes -= 16; -    } -    this.h[0] = h0; -    this.h[1] = h1; -    this.h[2] = h2; -    this.h[3] = h3; -    this.h[4] = h4; -    this.h[5] = h5; -    this.h[6] = h6; -    this.h[7] = h7; -    this.h[8] = h8; -    this.h[9] = h9; -  } - -  finish(mac: Uint8Array, macpos: number) { -    const g = new Uint16Array(10); -    let c, mask, f, i; - -    if (this.leftover) { -      i = this.leftover; -      this.buffer[i++] = 1; -      for (; i < 16; i++) this.buffer[i] = 0; -      this.fin = 1; -      this.blocks(this.buffer, 0, 16); -    } - -    c = this.h[1] >>> 13; -    this.h[1] &= 0x1fff; -    for (i = 2; i < 10; i++) { -      this.h[i] += c; -      c = this.h[i] >>> 13; -      this.h[i] &= 0x1fff; -    } -    this.h[0] += c * 5; -    c = this.h[0] >>> 13; -    this.h[0] &= 0x1fff; -    this.h[1] += c; -    c = this.h[1] >>> 13; -    this.h[1] &= 0x1fff; -    this.h[2] += c; - -    g[0] = this.h[0] + 5; -    c = g[0] >>> 13; -    g[0] &= 0x1fff; -    for (i = 1; i < 10; i++) { -      g[i] = this.h[i] + c; -      c = g[i] >>> 13; -      g[i] &= 0x1fff; -    } -    g[9] -= 1 << 13; - -    mask = (c ^ 1) - 1; -    for (i = 0; i < 10; i++) g[i] &= mask; -    mask = ~mask; -    for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; - -    this.h[0] = (this.h[0] | (this.h[1] << 13)) & 0xffff; -    this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff; -    this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff; -    this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff; -    this.h[4] = -      ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; -    this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff; -    this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff; -    this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff; - -    f = this.h[0] + this.pad[0]; -    this.h[0] = f & 0xffff; -    for (i = 1; i < 8; i++) { -      f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; -      this.h[i] = f & 0xffff; -    } - -    mac[macpos + 0] = (this.h[0] >>> 0) & 0xff; -    mac[macpos + 1] = (this.h[0] >>> 8) & 0xff; -    mac[macpos + 2] = (this.h[1] >>> 0) & 0xff; -    mac[macpos + 3] = (this.h[1] >>> 8) & 0xff; -    mac[macpos + 4] = (this.h[2] >>> 0) & 0xff; -    mac[macpos + 5] = (this.h[2] >>> 8) & 0xff; -    mac[macpos + 6] = (this.h[3] >>> 0) & 0xff; -    mac[macpos + 7] = (this.h[3] >>> 8) & 0xff; -    mac[macpos + 8] = (this.h[4] >>> 0) & 0xff; -    mac[macpos + 9] = (this.h[4] >>> 8) & 0xff; -    mac[macpos + 10] = (this.h[5] >>> 0) & 0xff; -    mac[macpos + 11] = (this.h[5] >>> 8) & 0xff; -    mac[macpos + 12] = (this.h[6] >>> 0) & 0xff; -    mac[macpos + 13] = (this.h[6] >>> 8) & 0xff; -    mac[macpos + 14] = (this.h[7] >>> 0) & 0xff; -    mac[macpos + 15] = (this.h[7] >>> 8) & 0xff; -  } - -  update(m: Uint8Array, mpos: number, bytes: number) { -    let i, want; - -    if (this.leftover) { -      want = 16 - this.leftover; -      if (want > bytes) want = bytes; -      for (i = 0; i < want; i++) this.buffer[this.leftover + i] = m[mpos + i]; -      bytes -= want; -      mpos += want; -      this.leftover += want; -      if (this.leftover < 16) return; -      this.blocks(this.buffer, 0, 16); -      this.leftover = 0; -    } - -    if (bytes >= 16) { -      want = bytes - (bytes % 16); -      this.blocks(m, mpos, want); -      mpos += want; -      bytes -= want; -    } - -    if (bytes) { -      for (i = 0; i < bytes; i++) this.buffer[this.leftover + i] = m[mpos + i]; -      this.leftover += bytes; -    } -  } -} - -function crypto_onetimeauth( -  out: Uint8Array, -  outpos: number, -  m: Uint8Array, -  mpos: number, -  n: number, -  k: Uint8Array, -) { -  const s = new poly1305(k); -  s.update(m, mpos, n); -  s.finish(out, outpos); -  return 0; -} - -function crypto_onetimeauth_verify( -  h: Uint8Array, -  hpos: number, -  m: Uint8Array, -  mpos: number, -  n: number, -  k: Uint8Array, -) { -  const x = new Uint8Array(16); -  crypto_onetimeauth(x, 0, m, mpos, n, k); -  return crypto_verify_16(h, hpos, x, 0); -} - -function crypto_secretbox( -  c: Uint8Array, -  m: Uint8Array, -  d: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  let i; -  if (d < 32) return -1; -  crypto_stream_xor(c, 0, m, 0, d, n, k); -  crypto_onetimeauth(c, 16, c, 32, d - 32, c); -  for (i = 0; i < 16; i++) c[i] = 0; -  return 0; -} - -function crypto_secretbox_open( -  m: Uint8Array, -  c: Uint8Array, -  d: number, -  n: Uint8Array, -  k: Uint8Array, -) { -  let i; -  const x = new Uint8Array(32); -  if (d < 32) return -1; -  crypto_stream(x, 0, 32, n, k); -  if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1; -  crypto_stream_xor(m, 0, c, 0, d, n, k); -  for (i = 0; i < 32; i++) m[i] = 0; -  return 0; -} - -function set25519(r: Float64Array, a: Float64Array) { +function set25519(r: Float64Array, a: Float64Array): void {    let i;    for (i = 0; i < 16; i++) r[i] = a[i] | 0;  } -function car25519(o: Float64Array) { +function car25519(o: Float64Array): void {    let i,      v,      c = 1; @@ -1166,9 +164,9 @@ function car25519(o: Float64Array) {    o[0] += c - 1 + 37 * (c - 1);  } -function sel25519(p: Float64Array, q: Float64Array, b: number) { -  let t, -    c = ~(b - 1); +function sel25519(p: Float64Array, q: Float64Array, b: number): void { +  let t; +  const c = ~(b - 1);    for (let i = 0; i < 16; i++) {      t = c & (p[i] ^ q[i]);      p[i] ^= t; @@ -1176,7 +174,7 @@ function sel25519(p: Float64Array, q: Float64Array, b: number) {    }  } -function pack25519(o: Uint8Array, n: Float64Array) { +function pack25519(o: Uint8Array, n: Float64Array): void {    let i, j, b;    const m = gf(),      t = gf(); @@ -1201,7 +199,7 @@ function pack25519(o: Uint8Array, n: Float64Array) {    }  } -function neq25519(a: Float64Array, b: Float64Array) { +function neq25519(a: Float64Array, b: Float64Array): number {    const c = new Uint8Array(32),      d = new Uint8Array(32);    pack25519(c, a); @@ -1209,27 +207,27 @@ function neq25519(a: Float64Array, b: Float64Array) {    return crypto_verify_32(c, 0, d, 0);  } -function par25519(a: Float64Array) { +function par25519(a: Float64Array): number {    const d = new Uint8Array(32);    pack25519(d, a);    return d[0] & 1;  } -function unpack25519(o: Float64Array, n: Uint8Array) { +function unpack25519(o: Float64Array, n: Uint8Array): void {    let i;    for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8);    o[15] &= 0x7fff;  } -function A(o: Float64Array, a: Float64Array, b: Float64Array) { +function A(o: Float64Array, a: Float64Array, b: Float64Array): void {    for (let i = 0; i < 16; i++) o[i] = a[i] + b[i];  } -function Z(o: Float64Array, a: Float64Array, b: Float64Array) { +function Z(o: Float64Array, a: Float64Array, b: Float64Array): void {    for (let i = 0; i < 16; i++) o[i] = a[i] - b[i];  } -function M(o: Float64Array, a: Float64Array, b: Float64Array) { +function M(o: Float64Array, a: Float64Array, b: Float64Array): void {    let v,      c,      t0 = 0, @@ -1262,8 +260,8 @@ function M(o: Float64Array, a: Float64Array, b: Float64Array) {      t27 = 0,      t28 = 0,      t29 = 0, -    t30 = 0, -    b0 = b[0], +    t30 = 0; +  const b0 = b[0],      b1 = b[1],      b2 = b[2],      b3 = b[3], @@ -1692,11 +690,11 @@ function M(o: Float64Array, a: Float64Array, b: Float64Array) {    o[15] = t15;  } -function S(o: Float64Array, a: Float64Array) { +function S(o: Float64Array, a: Float64Array): void {    M(o, a, a);  } -function inv25519(o: Float64Array, i: Float64Array) { +function inv25519(o: Float64Array, i: Float64Array): void {    const c = gf();    let a;    for (a = 0; a < 16; a++) c[a] = i[a]; @@ -1707,7 +705,7 @@ function inv25519(o: Float64Array, i: Float64Array) {    for (a = 0; a < 16; a++) o[a] = c[a];  } -function pow2523(o: Float64Array, i: Float64Array) { +function pow2523(o: Float64Array, i: Float64Array): void {    const c = gf();    let a;    for (a = 0; a < 16; a++) c[a] = i[a]; @@ -1718,11 +716,15 @@ function pow2523(o: Float64Array, i: Float64Array) {    for (a = 0; a < 16; a++) o[a] = c[a];  } -function crypto_scalarmult(q: Uint8Array, n: Uint8Array, p: Uint8Array) { +function crypto_scalarmult( +  q: Uint8Array, +  n: Uint8Array, +  p: Uint8Array, +): number {    const z = new Uint8Array(32); -  let x = new Float64Array(80), -    r, -    i; +  const x = new Float64Array(80); +  let r; +  let i;    const a = gf(),      b = gf(),      c = gf(), @@ -1777,50 +779,10 @@ function crypto_scalarmult(q: Uint8Array, n: Uint8Array, p: Uint8Array) {    return 0;  } -function crypto_scalarmult_base(q: Uint8Array, n: Uint8Array) { +function crypto_scalarmult_base(q: Uint8Array, n: Uint8Array): number {    return crypto_scalarmult(q, n, _9);  } -function crypto_box_keypair(y: Uint8Array, x: Uint8Array) { -  randombytes(x, 32); -  return crypto_scalarmult_base(y, x); -} - -function crypto_box_beforenm(k: Uint8Array, y: Uint8Array, x: Uint8Array) { -  const s = new Uint8Array(32); -  crypto_scalarmult(s, x, y); -  return crypto_core_hsalsa20(k, _0, s, sigma); -} - -const crypto_box_afternm = crypto_secretbox; -const crypto_box_open_afternm = crypto_secretbox_open; - -function crypto_box( -  c: Uint8Array, -  m: Uint8Array, -  d: number, -  n: Uint8Array, -  y: Uint8Array, -  x: Uint8Array, -) { -  const k = new Uint8Array(32); -  crypto_box_beforenm(k, y, x); -  return crypto_box_afternm(c, m, d, n, k); -} - -function crypto_box_open( -  m: Uint8Array, -  c: Uint8Array, -  d: number, -  n: Uint8Array, -  y: Uint8Array, -  x: Uint8Array, -) { -  const k = new Uint8Array(32); -  crypto_box_beforenm(k, y, x); -  return crypto_box_open_afternm(m, c, d, n, k); -} -  // prettier-ignore  const K = [    0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, @@ -1870,10 +832,10 @@ function crypto_hashblocks_hl(    hl: Int32Array,    m: Uint8Array,    n: number, -) { -  let wh = new Int32Array(16), -    wl = new Int32Array(16), -    bh0, +): number { +  const wh = new Int32Array(16), +    wl = new Int32Array(16); +  let bh0,      bh1,      bh2,      bh3, @@ -2338,7 +1300,7 @@ function crypto_hashblocks_hl(    return n;  } -function crypto_hash(out: Uint8Array, m: Uint8Array, n: number) { +function crypto_hash(out: Uint8Array, m: Uint8Array, n: number): number {    const hh = new Int32Array(8);    const hl = new Int32Array(8);    const x = new Uint8Array(256); @@ -2450,7 +1412,7 @@ export class HashState {    }  } -function add(p: Float64Array[], q: Float64Array[]) { +function add(p: Float64Array[], q: Float64Array[]): void {    const a = gf(),      b = gf(),      c = gf(), @@ -2482,14 +1444,14 @@ function add(p: Float64Array[], q: Float64Array[]) {    M(p[3], e, h);  } -function cswap(p: Float64Array[], q: Float64Array[], b: number) { +function cswap(p: Float64Array[], q: Float64Array[], b: number): void {    let i;    for (i = 0; i < 4; i++) {      sel25519(p[i], q[i], b);    }  } -function pack(r: Uint8Array, p: Float64Array[]) { +function pack(r: Uint8Array, p: Float64Array[]): void {    const tx = gf(),      ty = gf(),      zi = gf(); @@ -2500,7 +1462,7 @@ function pack(r: Uint8Array, p: Float64Array[]) {    r[31] ^= par25519(tx) << 7;  } -function scalarmult(p: Float64Array[], q: Float64Array[], s: Uint8Array) { +function scalarmult(p: Float64Array[], q: Float64Array[], s: Uint8Array): void {    let b, i;    set25519(p[0], gf0);    set25519(p[1], gf1); @@ -2515,7 +1477,7 @@ function scalarmult(p: Float64Array[], q: Float64Array[], s: Uint8Array) {    }  } -function scalarbase(p: Float64Array[], s: Uint8Array) { +function scalarbase(p: Float64Array[], s: Uint8Array): void {    const q = [gf(), gf(), gf(), gf()];    set25519(q[0], X);    set25519(q[1], Y); @@ -2580,7 +1542,7 @@ const L = new Float64Array([    0x10,  ]); -function modL(r: Uint8Array, x: Float64Array) { +function modL(r: Uint8Array, x: Float64Array): void {    let carry, i, j, k;    for (i = 63; i >= 32; --i) {      carry = 0; @@ -2605,7 +1567,7 @@ function modL(r: Uint8Array, x: Float64Array) {    }  } -function reduce(r: Uint8Array) { +function reduce(r: Uint8Array): void {    const x = new Float64Array(64);    for (let i = 0; i < 64; i++) x[i] = r[i];    for (let i = 0; i < 64; i++) r[i] = 0; @@ -2613,13 +1575,17 @@ function reduce(r: Uint8Array) {  }  // Note: difference from C - smlen returned, not passed as argument. -function crypto_sign(sm: Uint8Array, m: Uint8Array, n: number, sk: Uint8Array) { +function crypto_sign( +  sm: Uint8Array, +  m: Uint8Array, +  n: number, +  sk: Uint8Array, +): number {    const d = new Uint8Array(64),      h = new Uint8Array(64),      r = new Uint8Array(64); -  let i, -    j, -    x = new Float64Array(64); +  let i, j; +  const x = new Float64Array(64);    const p = [gf(), gf(), gf(), gf()];    crypto_hash(d, sk, 32); @@ -2652,7 +1618,7 @@ function crypto_sign(sm: Uint8Array, m: Uint8Array, n: number, sk: Uint8Array) {    return smlen;  } -function unpackneg(r: Float64Array[], p: Uint8Array) { +function unpackneg(r: Float64Array[], p: Uint8Array): number {    const t = gf();    const chk = gf();    const num = gf(); @@ -2699,7 +1665,7 @@ function crypto_sign_open(    sm: Uint8Array,    n: number,    pk: Uint8Array, -) { +): number {    let i, mlen;    const t = new Uint8Array(32),      h = new Uint8Array(64); @@ -2732,131 +1698,34 @@ function crypto_sign_open(    return mlen;  } -const crypto_secretbox_KEYBYTES = 32, -  crypto_secretbox_NONCEBYTES = 24, -  crypto_secretbox_ZEROBYTES = 32, -  crypto_secretbox_BOXZEROBYTES = 16, -  crypto_scalarmult_BYTES = 32, +const crypto_scalarmult_BYTES = 32,    crypto_scalarmult_SCALARBYTES = 32, -  crypto_box_PUBLICKEYBYTES = 32, -  crypto_box_SECRETKEYBYTES = 32, -  crypto_box_BEFORENMBYTES = 32, -  crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, -  crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, -  crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,    crypto_sign_BYTES = 64,    crypto_sign_PUBLICKEYBYTES = 32,    crypto_sign_SECRETKEYBYTES = 64,    crypto_sign_SEEDBYTES = 32,    crypto_hash_BYTES = 64; -const lowlevel = { -  crypto_core_hsalsa20: crypto_core_hsalsa20, -  crypto_stream_xor: crypto_stream_xor, -  crypto_stream: crypto_stream, -  crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, -  crypto_stream_salsa20: crypto_stream_salsa20, -  crypto_onetimeauth: crypto_onetimeauth, -  crypto_onetimeauth_verify: crypto_onetimeauth_verify, -  crypto_verify_16: crypto_verify_16, -  crypto_verify_32: crypto_verify_32, -  crypto_secretbox: crypto_secretbox, -  crypto_secretbox_open: crypto_secretbox_open, -  crypto_scalarmult: crypto_scalarmult, -  crypto_scalarmult_base: crypto_scalarmult_base, -  crypto_box_beforenm: crypto_box_beforenm, -  crypto_box_afternm: crypto_box_afternm, -  crypto_box: crypto_box, -  crypto_box_open: crypto_box_open, -  crypto_box_keypair: crypto_box_keypair, -  crypto_hash: crypto_hash, -  crypto_sign: crypto_sign, -  crypto_sign_keypair: crypto_sign_keypair, -  crypto_sign_open: crypto_sign_open, - -  crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, -  crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, -  crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, -  crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, -  crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, -  crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, -  crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, -  crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, -  crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, -  crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, -  crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, -  crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, -  crypto_sign_BYTES: crypto_sign_BYTES, -  crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, -  crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, -  crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, -  crypto_hash_BYTES: crypto_hash_BYTES, -}; -  /* High-level API */ -function checkLengths(k: Uint8Array, n: Uint8Array) { -  if (k.length !== crypto_secretbox_KEYBYTES) throw new Error("bad key size"); -  if (n.length !== crypto_secretbox_NONCEBYTES) -    throw new Error("bad nonce size"); -} - -function checkBoxLengths(pk: Uint8Array, sk: Uint8Array) { -  if (pk.length !== crypto_box_PUBLICKEYBYTES) -    throw new Error("bad public key size"); -  if (sk.length !== crypto_box_SECRETKEYBYTES) -    throw new Error("bad secret key size"); -} - -function checkArrayTypes(...args: Uint8Array[]) { +function checkArrayTypes(...args: Uint8Array[]): void {    for (let i = 0; i < args.length; i++) {      if (!(args[i] instanceof Uint8Array))        throw new TypeError("unexpected type, use Uint8Array");    }  } -function cleanup(arr: Uint8Array) { +function cleanup(arr: Uint8Array): void {    for (let i = 0; i < arr.length; i++) arr[i] = 0;  } -export function randomBytes(n: number) { +export function randomBytes(n: number): Uint8Array {    const b = new Uint8Array(n);    randombytes(b, n);    return b;  } -export function secretbox(msg: Uint8Array, nonce: Uint8Array, key: Uint8Array) { -  checkArrayTypes(msg, nonce, key); -  checkLengths(key, nonce); -  const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); -  const c = new Uint8Array(m.length); -  for (let i = 0; i < msg.length; i++) -    m[i + crypto_secretbox_ZEROBYTES] = msg[i]; -  crypto_secretbox(c, m, m.length, nonce, key); -  return c.subarray(crypto_secretbox_BOXZEROBYTES); -} - -export function secretbox_open( -  box: Uint8Array, -  nonce: Uint8Array, -  key: Uint8Array, -) { -  checkArrayTypes(box, nonce, key); -  checkLengths(key, nonce); -  const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); -  const m = new Uint8Array(c.length); -  for (let i = 0; i < box.length; i++) -    c[i + crypto_secretbox_BOXZEROBYTES] = box[i]; -  if (c.length < 32) return null; -  if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null; -  return m.subarray(crypto_secretbox_ZEROBYTES); -} - -export const secretbox_keyLength = crypto_secretbox_KEYBYTES; -export const secretbox_nonceLength = crypto_secretbox_NONCEBYTES; -export const secretbox_overheadLength = crypto_secretbox_BOXZEROBYTES; - -export function scalarMult(n: Uint8Array, p: Uint8Array) { +export function scalarMult(n: Uint8Array, p: Uint8Array): Uint8Array {    checkArrayTypes(n, p);    if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");    if (p.length !== crypto_scalarmult_BYTES) throw new Error("bad p size"); @@ -2865,7 +1734,7 @@ export function scalarMult(n: Uint8Array, p: Uint8Array) {    return q;  } -export function scalarMult_base(n: Uint8Array) { +export function scalarMult_base(n: Uint8Array): Uint8Array {    checkArrayTypes(n);    if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");    const q = new Uint8Array(crypto_scalarmult_BYTES); @@ -2876,61 +1745,7 @@ export function scalarMult_base(n: Uint8Array) {  export const scalarMult_scalarLength = crypto_scalarmult_SCALARBYTES;  export const scalarMult_groupElementLength = crypto_scalarmult_BYTES; -export function box( -  msg: Uint8Array, -  nonce: Uint8Array, -  publicKey: Uint8Array, -  secretKey: Uint8Array, -) { -  const k = box_before(publicKey, secretKey); -  return secretbox(msg, nonce, k); -} - -export function box_before(publicKey: Uint8Array, secretKey: Uint8Array) { -  checkArrayTypes(publicKey, secretKey); -  checkBoxLengths(publicKey, secretKey); -  const k = new Uint8Array(crypto_box_BEFORENMBYTES); -  crypto_box_beforenm(k, publicKey, secretKey); -  return k; -} - -export const box_after = secretbox; - -export function box_open( -  msg: Uint8Array, -  nonce: Uint8Array, -  publicKey: Uint8Array, -  secretKey: Uint8Array, -) { -  const k = box_before(publicKey, secretKey); -  return secretbox_open(msg, nonce, k); -} - -export const box_open_after = secretbox_open; - -export function box_keyPair() { -  const pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); -  const sk = new Uint8Array(crypto_box_SECRETKEYBYTES); -  crypto_box_keypair(pk, sk); -  return { publicKey: pk, secretKey: sk }; -} - -export function box_keyPair_fromSecretKey(secretKey: Uint8Array) { -  checkArrayTypes(secretKey); -  if (secretKey.length !== crypto_box_SECRETKEYBYTES) -    throw new Error("bad secret key size"); -  const pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); -  crypto_scalarmult_base(pk, secretKey); -  return { publicKey: pk, secretKey: new Uint8Array(secretKey) }; -} - -export const box_publicKeyLength = crypto_box_PUBLICKEYBYTES; -export const box_secretKeyLength = crypto_box_SECRETKEYBYTES; -export const box_sharedKeyLength = crypto_box_BEFORENMBYTES; -export const box_nonceLength = crypto_box_NONCEBYTES; -export const box_overheadLength = secretbox_overheadLength; - -export function sign(msg: Uint8Array, secretKey: Uint8Array) { +export function sign(msg: Uint8Array, secretKey: Uint8Array): Uint8Array {    checkArrayTypes(msg, secretKey);    if (secretKey.length !== crypto_sign_SECRETKEYBYTES)      throw new Error("bad secret key size"); @@ -2939,7 +1754,10 @@ export function sign(msg: Uint8Array, secretKey: Uint8Array) {    return signedMsg;  } -export function sign_open(signedMsg: Uint8Array, publicKey: Uint8Array) { +export function sign_open( +  signedMsg: Uint8Array, +  publicKey: Uint8Array, +): Uint8Array | null {    checkArrayTypes(signedMsg, publicKey);    if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)      throw new Error("bad public key size"); @@ -2951,7 +1769,10 @@ export function sign_open(signedMsg: Uint8Array, publicKey: Uint8Array) {    return m;  } -export function sign_detached(msg: Uint8Array, secretKey: Uint8Array) { +export function sign_detached( +  msg: Uint8Array, +  secretKey: Uint8Array, +): Uint8Array {    const signedMsg = sign(msg, secretKey);    const sig = new Uint8Array(crypto_sign_BYTES);    for (let i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; @@ -2962,7 +1783,7 @@ export function sign_detached_verify(    msg: Uint8Array,    sig: Uint8Array,    publicKey: Uint8Array, -) { +): boolean {    checkArrayTypes(msg, sig, publicKey);    if (sig.length !== crypto_sign_BYTES) throw new Error("bad signature size");    if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) @@ -2975,7 +1796,10 @@ export function sign_detached_verify(    return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;  } -export function sign_keyPair() { +export function sign_keyPair(): { +  publicKey: Uint8Array; +  secretKey: Uint8Array; +} {    const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);    const sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);    crypto_sign_keypair(pk, sk, false); @@ -3005,7 +1829,12 @@ export function x25519_edwards_keyPair_fromSecretKey(    return pk;  } -export function sign_keyPair_fromSecretKey(secretKey: Uint8Array) { +export function sign_keyPair_fromSecretKey( +  secretKey: Uint8Array, +): { +  publicKey: Uint8Array; +  secretKey: Uint8Array; +} {    checkArrayTypes(secretKey);    if (secretKey.length !== crypto_sign_SECRETKEYBYTES)      throw new Error("bad secret key size"); @@ -3014,7 +1843,12 @@ export function sign_keyPair_fromSecretKey(secretKey: Uint8Array) {    return { publicKey: pk, secretKey: new Uint8Array(secretKey) };  } -export function sign_keyPair_fromSeed(seed: Uint8Array) { +export function sign_keyPair_fromSeed( +  seed: Uint8Array, +): { +  publicKey: Uint8Array; +  secretKey: Uint8Array; +} {    checkArrayTypes(seed);    if (seed.length !== crypto_sign_SEEDBYTES) throw new Error("bad seed size");    const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); @@ -3029,7 +1863,7 @@ export const sign_secretKeyLength = crypto_sign_SECRETKEYBYTES;  export const sign_seedLength = crypto_sign_SEEDBYTES;  export const sign_signatureLength = crypto_sign_BYTES; -export function hash(msg: Uint8Array) { +export function hash(msg: Uint8Array): Uint8Array {    checkArrayTypes(msg);    const h = new Uint8Array(crypto_hash_BYTES);    crypto_hash(h, msg, msg.length); @@ -3038,7 +1872,7 @@ export function hash(msg: Uint8Array) {  export const hash_hashLength = crypto_hash_BYTES; -export function verify(x: Uint8Array, y: Uint8Array) { +export function verify(x: Uint8Array, y: Uint8Array): boolean {    checkArrayTypes(x, y);    // Zero length arguments are considered not equal.    if (x.length === 0 || y.length === 0) return false; @@ -3046,7 +1880,7 @@ export function verify(x: Uint8Array, y: Uint8Array) {    return vn(x, 0, y, 0, x.length) === 0 ? true : false;  } -export function setPRNG(fn: (x: Uint8Array, n: number) => void) { +export function setPRNG(fn: (x: Uint8Array, n: number) => void): void {    randombytes = fn;  } @@ -3084,8 +1918,8 @@ export function sign_ed25519_pk_to_curve25519(      // Browsers.      const QUOTA = 65536;      setPRNG(function (x: Uint8Array, n: number) { -      let i, -        v = new Uint8Array(n); +      let i; +      const v = new Uint8Array(n);        for (i = 0; i < n; i += QUOTA) {          cr.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));        } @@ -3094,12 +1928,12 @@ export function sign_ed25519_pk_to_curve25519(      });    } else if (typeof require !== "undefined") {      // Node.js. +    // eslint-disable-next-line @typescript-eslint/no-var-requires      const cr = require("crypto");      if (cr && cr.randomBytes) {        setPRNG(function (x: Uint8Array, n: number) { -        let i, -          v = cr.randomBytes(n); -        for (i = 0; i < n; i++) x[i] = v[i]; +        const v = cr.randomBytes(n); +        for (let i = 0; i < n; i++) x[i] = v[i];          cleanup(v);        });      } diff --git a/src/operations/pay.ts b/src/operations/pay.ts index 3a629e9c2..337068b55 100644 --- a/src/operations/pay.ts +++ b/src/operations/pay.ts @@ -620,7 +620,7 @@ export async function processDownloadProposal(    proposalId: string,    forceNow = false,  ): Promise<void> { -  const onOpErr = (err: OperationError) => +  const onOpErr = (err: OperationError): Promise<void> =>      incrementProposalRetry(ws, proposalId, err);    await guardOperationException(      () => processDownloadProposalImpl(ws, proposalId, forceNow), @@ -631,7 +631,7 @@ export async function processDownloadProposal(  async function resetDownloadProposalRetry(    ws: InternalWalletState,    proposalId: string, -) { +): Promise<void> {    await ws.db.mutate(Stores.proposals, proposalId, (x) => {      if (x.retryInfo.active) {        x.retryInfo = initRetryInfo(); @@ -1108,7 +1108,7 @@ export async function processPurchasePay(    proposalId: string,    forceNow = false,  ): Promise<void> { -  const onOpErr = (e: OperationError) => +  const onOpErr = (e: OperationError): Promise<void> =>      incrementPurchasePayRetry(ws, proposalId, e);    await guardOperationException(      () => processPurchasePayImpl(ws, proposalId, forceNow), @@ -1119,7 +1119,7 @@ export async function processPurchasePay(  async function resetPurchasePayRetry(    ws: InternalWalletState,    proposalId: string, -) { +): Promise<void> {    await ws.db.mutate(Stores.purchases, proposalId, (x) => {      if (x.payRetryInfo.active) {        x.payRetryInfo = initRetryInfo(); @@ -1150,7 +1150,7 @@ async function processPurchasePayImpl(  export async function refuseProposal(    ws: InternalWalletState,    proposalId: string, -) { +): Promise<void> {    const success = await ws.db.runWithWriteTransaction(      [Stores.proposals],      async (tx) => { diff --git a/src/operations/refund.ts b/src/operations/refund.ts index 74d4b848e..af9a48895 100644 --- a/src/operations/refund.ts +++ b/src/operations/refund.ts @@ -302,7 +302,7 @@ export async function processPurchaseQueryRefund(    proposalId: string,    forceNow = false,  ): Promise<void> { -  const onOpErr = (e: OperationError) => +  const onOpErr = (e: OperationError): Promise<void> =>      incrementPurchaseQueryRefundRetry(ws, proposalId, e);    await guardOperationException(      () => processPurchaseQueryRefundImpl(ws, proposalId, forceNow), @@ -313,7 +313,7 @@ export async function processPurchaseQueryRefund(  async function resetPurchaseQueryRefundRetry(    ws: InternalWalletState,    proposalId: string, -) { +): Promise<void> {    await ws.db.mutate(Stores.purchases, proposalId, (x) => {      if (x.refundStatusRetryInfo.active) {        x.refundStatusRetryInfo = initRetryInfo(); @@ -368,7 +368,7 @@ export async function processPurchaseApplyRefund(    proposalId: string,    forceNow = false,  ): Promise<void> { -  const onOpErr = (e: OperationError) => +  const onOpErr = (e: OperationError): Promise<void> =>      incrementPurchaseApplyRefundRetry(ws, proposalId, e);    await guardOperationException(      () => processPurchaseApplyRefundImpl(ws, proposalId, forceNow), @@ -379,7 +379,7 @@ export async function processPurchaseApplyRefund(  async function resetPurchaseApplyRefundRetry(    ws: InternalWalletState,    proposalId: string, -) { +): Promise<void> {    await ws.db.mutate(Stores.purchases, proposalId, (x) => {      if (x.refundApplyRetryInfo.active) {        x.refundApplyRetryInfo = initRetryInfo(); @@ -435,11 +435,10 @@ async function processPurchaseApplyRefundImpl(          // We're too late, refund is expired.          newRefundsFailed[pk] = info;          break; -      default: +      default: {          let body: string | null = null; -        try { -          body = await resp.json(); -        } catch {} +        // FIXME: error handling! +        body = await resp.json();          const m = "refund request (at exchange) failed";          throw new OperationFailedError({            message: m, @@ -448,6 +447,7 @@ async function processPurchaseApplyRefundImpl(              body,            },          }); +      }      }    }    let allRefundsProcessed = false; diff --git a/src/types/ReserveStatus.ts b/src/types/ReserveStatus.ts index 8ab7225e8..5a3011b37 100644 --- a/src/types/ReserveStatus.ts +++ b/src/types/ReserveStatus.ts @@ -23,11 +23,9 @@   */  import {    codecForString, -  typecheckedCodec,    makeCodecForObject, -  makeCodecForConstString, -  makeCodecForUnion,    makeCodecForList, +  Codec,  } from "../util/codec";  import { AmountString } from "./talerTypes";  import { @@ -52,10 +50,8 @@ export interface ReserveStatus {    history: ReserveTransaction[];  } -export const codecForReserveStatus = () => -  typecheckedCodec<ReserveStatus>( +export const codecForReserveStatus = (): Codec<ReserveStatus> =>      makeCodecForObject<ReserveStatus>()        .property("balance", codecForString)        .property("history", makeCodecForList(codecForReserveTransaction())) -      .build("ReserveStatus"), -  ); +      .build("ReserveStatus"); diff --git a/src/types/ReserveTransaction.ts b/src/types/ReserveTransaction.ts index cebccd2dc..acbd502ea 100644 --- a/src/types/ReserveTransaction.ts +++ b/src/types/ReserveTransaction.ts @@ -23,10 +23,10 @@   */  import {    codecForString, -  typecheckedCodec,    makeCodecForObject,    makeCodecForConstString,    makeCodecForUnion, +  Codec,  } from "../util/codec";  import {    AmountString, @@ -179,8 +179,7 @@ export type ReserveTransaction =    | ReserveClosingTransaction    | ReserveRecoupTransaction; -export const codecForReserveWithdrawTransaction = () => -  typecheckedCodec<ReserveWithdrawTransaction>( +export const codecForReserveWithdrawTransaction = (): Codec<ReserveWithdrawTransaction> =>      makeCodecForObject<ReserveWithdrawTransaction>()        .property("amount", codecForString)        .property("h_coin_envelope", codecForString) @@ -191,22 +190,18 @@ export const codecForReserveWithdrawTransaction = () =>          makeCodecForConstString(ReserveTransactionType.Withdraw),        )        .property("withdraw_fee", codecForString) -      .build("ReserveWithdrawTransaction"), -  ); +      .build("ReserveWithdrawTransaction"); -export const codecForReserveCreditTransaction = () => -  typecheckedCodec<ReserveCreditTransaction>( +export const codecForReserveCreditTransaction = (): Codec<ReserveCreditTransaction> =>      makeCodecForObject<ReserveCreditTransaction>()        .property("amount", codecForString)        .property("sender_account_url", codecForString)        .property("timestamp", codecForTimestamp)        .property("wire_reference", codecForString)        .property("type", makeCodecForConstString(ReserveTransactionType.Credit)) -      .build("ReserveCreditTransaction"), -  ); +      .build("ReserveCreditTransaction"); -export const codecForReserveClosingTransaction = () => -  typecheckedCodec<ReserveClosingTransaction>( +export const codecForReserveClosingTransaction = (): Codec<ReserveClosingTransaction> =>      makeCodecForObject<ReserveClosingTransaction>()        .property("amount", codecForString)        .property("closing_fee", codecForString) @@ -216,11 +211,9 @@ export const codecForReserveClosingTransaction = () =>        .property("timestamp", codecForTimestamp)        .property("type", makeCodecForConstString(ReserveTransactionType.Closing))        .property("wtid", codecForString) -      .build("ReserveClosingTransaction"), -  ); +      .build("ReserveClosingTransaction"); -export const codecForReserveRecoupTransaction = () => -  typecheckedCodec<ReserveRecoupTransaction>( +export const codecForReserveRecoupTransaction = (): Codec<ReserveRecoupTransaction> =>      makeCodecForObject<ReserveRecoupTransaction>()        .property("amount", codecForString)        .property("coin_pub", codecForString) @@ -228,11 +221,9 @@ export const codecForReserveRecoupTransaction = () =>        .property("exchange_sig", codecForString)        .property("timestamp", codecForTimestamp)        .property("type", makeCodecForConstString(ReserveTransactionType.Recoup)) -      .build("ReserveRecoupTransaction"), -  ); +      .build("ReserveRecoupTransaction"); -export const codecForReserveTransaction = () => -  typecheckedCodec<ReserveTransaction>( +export const codecForReserveTransaction = (): Codec<ReserveTransaction> =>      makeCodecForUnion<ReserveTransaction>()        .discriminateOn("type")        .alternative( @@ -251,5 +242,4 @@ export const codecForReserveTransaction = () =>          ReserveTransactionType.Credit,          codecForReserveCreditTransaction(),        ) -      .build<ReserveTransaction>("ReserveTransaction"), -  ); +      .build<ReserveTransaction>("ReserveTransaction"); diff --git a/src/types/talerTypes.ts b/src/types/talerTypes.ts index 0f35f7ede..74157b18b 100644 --- a/src/types/talerTypes.ts +++ b/src/types/talerTypes.ts @@ -28,7 +28,6 @@   */  import { -  typecheckedCodec,    makeCodecForObject,    codecForString,    makeCodecForList, @@ -37,6 +36,7 @@ import {    codecForNumber,    codecForBoolean,    makeCodecForMap, +  Codec,  } from "../util/codec";  import {    Timestamp, @@ -786,222 +786,183 @@ export type EddsaSignatureString = string;  export type EddsaPublicKeyString = string;  export type CoinPublicKeyString = string; -export const codecForDenomination = () => -  typecheckedCodec<Denomination>( -    makeCodecForObject<Denomination>() -      .property("value", codecForString) -      .property("denom_pub", codecForString) -      .property("fee_withdraw", codecForString) -      .property("fee_deposit", codecForString) -      .property("fee_refresh", codecForString) -      .property("fee_refund", codecForString) -      .property("stamp_start", codecForTimestamp) -      .property("stamp_expire_withdraw", codecForTimestamp) -      .property("stamp_expire_legal", codecForTimestamp) -      .property("stamp_expire_deposit", codecForTimestamp) -      .property("master_sig", codecForString) -      .build("Denomination"), -  ); - -export const codecForAuditorDenomSig = () => -  typecheckedCodec<AuditorDenomSig>( -    makeCodecForObject<AuditorDenomSig>() -      .property("denom_pub_h", codecForString) -      .property("auditor_sig", codecForString) -      .build("AuditorDenomSig"), -  ); - -export const codecForAuditor = () => -  typecheckedCodec<Auditor>( -    makeCodecForObject<Auditor>() -      .property("auditor_pub", codecForString) -      .property("auditor_url", codecForString) -      .property( -        "denomination_keys", -        makeCodecForList(codecForAuditorDenomSig()), -      ) -      .build("Auditor"), -  ); - -export const codecForExchangeHandle = () => -  typecheckedCodec<ExchangeHandle>( -    makeCodecForObject<ExchangeHandle>() -      .property("master_pub", codecForString) -      .property("url", codecForString) -      .build("ExchangeHandle"), -  ); - -export const codecForAuditorHandle = () => -  typecheckedCodec<AuditorHandle>( -    makeCodecForObject<AuditorHandle>() -      .property("name", codecForString) -      .property("master_pub", codecForString) -      .property("url", codecForString) -      .build("AuditorHandle"), -  ); - -export const codecForContractTerms = () => -  typecheckedCodec<ContractTerms>( -    makeCodecForObject<ContractTerms>() -      .property("order_id", codecForString) -      .property("fulfillment_url", codecForString) -      .property("merchant_base_url", codecForString) -      .property("h_wire", codecForString) -      .property("auto_refund", makeCodecOptional(codecForDuration)) -      .property("wire_method", codecForString) -      .property("summary", codecForString) -      .property("nonce", codecForString) -      .property("amount", codecForString) -      .property("auditors", makeCodecForList(codecForAuditorHandle())) -      .property("pay_deadline", codecForTimestamp) -      .property("refund_deadline", codecForTimestamp) -      .property("wire_transfer_deadline", codecForTimestamp) -      .property("timestamp", codecForTimestamp) -      .property("locations", codecForAny) -      .property("max_fee", codecForString) -      .property("max_wire_fee", makeCodecOptional(codecForString)) -      .property("merchant", codecForAny) -      .property("merchant_pub", codecForString) -      .property("exchanges", makeCodecForList(codecForExchangeHandle())) -      .property("products", makeCodecOptional(makeCodecForList(codecForAny))) -      .property("extra", codecForAny) -      .build("ContractTerms"), -  ); - -export const codecForMerchantRefundPermission = () => -  typecheckedCodec<MerchantRefundPermission>( -    makeCodecForObject<MerchantRefundPermission>() -      .property("refund_amount", codecForString) -      .property("refund_fee", codecForString) -      .property("coin_pub", codecForString) -      .property("rtransaction_id", codecForNumber) -      .property("merchant_sig", codecForString) -      .build("MerchantRefundPermission"), -  ); - -export const codecForMerchantRefundResponse = () => -  typecheckedCodec<MerchantRefundResponse>( -    makeCodecForObject<MerchantRefundResponse>() -      .property("merchant_pub", codecForString) -      .property("h_contract_terms", codecForString) -      .property( -        "refund_permissions", -        makeCodecForList(codecForMerchantRefundPermission()), -      ) -      .build("MerchantRefundResponse"), -  ); - -export const codecForReserveSigSingleton = () => -  typecheckedCodec<ReserveSigSingleton>( -    makeCodecForObject<ReserveSigSingleton>() -      .property("reserve_sig", codecForString) -      .build("ReserveSigSingleton"), -  ); - -export const codecForTipResponse = () => -  typecheckedCodec<TipResponse>( -    makeCodecForObject<TipResponse>() -      .property("reserve_pub", codecForString) -      .property("reserve_sigs", makeCodecForList(codecForReserveSigSingleton())) -      .build("TipResponse"), -  ); - -export const codecForRecoup = () => -  typecheckedCodec<Recoup>( -    makeCodecForObject<Recoup>() -      .property("h_denom_pub", codecForString) -      .build("Payback"), -  ); - -export const codecForExchangeSigningKey = () => -  typecheckedCodec<ExchangeSignKeyJson>( -    makeCodecForObject<ExchangeSignKeyJson>() -      .property("key", codecForString) -      .property("master_sig", codecForString) -      .property("stamp_end", codecForTimestamp) -      .property("stamp_start", codecForTimestamp) -      .property("stamp_expire", codecForTimestamp) -      .build("ExchangeSignKeyJson"), -  ); - -export const codecForExchangeKeysJson = () => -  typecheckedCodec<ExchangeKeysJson>( -    makeCodecForObject<ExchangeKeysJson>() -      .property("denoms", makeCodecForList(codecForDenomination())) -      .property("master_public_key", codecForString) -      .property("auditors", makeCodecForList(codecForAuditor())) -      .property("list_issue_date", codecForTimestamp) -      .property("recoup", makeCodecOptional(makeCodecForList(codecForRecoup()))) -      .property("signkeys", makeCodecForList(codecForExchangeSigningKey())) -      .property("version", codecForString) -      .build("KeysJson"), -  ); - -export const codecForWireFeesJson = () => -  typecheckedCodec<WireFeesJson>( -    makeCodecForObject<WireFeesJson>() -      .property("wire_fee", codecForString) -      .property("closing_fee", codecForString) -      .property("sig", codecForString) -      .property("start_date", codecForTimestamp) -      .property("end_date", codecForTimestamp) -      .build("WireFeesJson"), -  ); - -export const codecForAccountInfo = () => -  typecheckedCodec<AccountInfo>( -    makeCodecForObject<AccountInfo>() -      .property("payto_uri", codecForString) -      .property("master_sig", codecForString) -      .build("AccountInfo"), -  ); - -export const codecForExchangeWireJson = () => -  typecheckedCodec<ExchangeWireJson>( -    makeCodecForObject<ExchangeWireJson>() -      .property("accounts", makeCodecForList(codecForAccountInfo())) -      .property( -        "fees", -        makeCodecForMap(makeCodecForList(codecForWireFeesJson())), -      ) -      .build("ExchangeWireJson"), -  ); - -export const codecForProposal = () => -  typecheckedCodec<Proposal>( -    makeCodecForObject<Proposal>() -      .property("contract_terms", codecForAny) -      .property("sig", codecForString) -      .build("Proposal"), -  ); - -export const codecForCheckPaymentResponse = () => -  typecheckedCodec<CheckPaymentResponse>( -    makeCodecForObject<CheckPaymentResponse>() -      .property("paid", codecForBoolean) -      .property("refunded", makeCodecOptional(codecForBoolean)) -      .property("refunded_amount", makeCodecOptional(codecForString)) -      .property("contract_terms", makeCodecOptional(codecForAny)) -      .property("taler_pay_uri", makeCodecOptional(codecForString)) -      .property("contract_url", makeCodecOptional(codecForString)) -      .build("CheckPaymentResponse"), -  ); - -export const codecForWithdrawOperationStatusResponse = () => -  typecheckedCodec<WithdrawOperationStatusResponse>( -    makeCodecForObject<WithdrawOperationStatusResponse>() -      .property("selection_done", codecForBoolean) -      .property("transfer_done", codecForBoolean) -      .property("amount", codecForString) -      .property("sender_wire", makeCodecOptional(codecForString)) -      .property("suggested_exchange", makeCodecOptional(codecForString)) -      .property("confirm_transfer_url", makeCodecOptional(codecForString)) -      .property("wire_types", makeCodecForList(codecForString)) -      .build("WithdrawOperationStatusResponse"), -  ); - -export const codecForTipPickupGetResponse = () => -  typecheckedCodec<TipPickupGetResponse>( +export const codecForDenomination = (): Codec<Denomination> => +  makeCodecForObject<Denomination>() +    .property("value", codecForString) +    .property("denom_pub", codecForString) +    .property("fee_withdraw", codecForString) +    .property("fee_deposit", codecForString) +    .property("fee_refresh", codecForString) +    .property("fee_refund", codecForString) +    .property("stamp_start", codecForTimestamp) +    .property("stamp_expire_withdraw", codecForTimestamp) +    .property("stamp_expire_legal", codecForTimestamp) +    .property("stamp_expire_deposit", codecForTimestamp) +    .property("master_sig", codecForString) +    .build("Denomination"); + +export const codecForAuditorDenomSig = (): Codec<AuditorDenomSig> => +  makeCodecForObject<AuditorDenomSig>() +    .property("denom_pub_h", codecForString) +    .property("auditor_sig", codecForString) +    .build("AuditorDenomSig"); + +export const codecForAuditor = (): Codec<Auditor> => +  makeCodecForObject<Auditor>() +    .property("auditor_pub", codecForString) +    .property("auditor_url", codecForString) +    .property("denomination_keys", makeCodecForList(codecForAuditorDenomSig())) +    .build("Auditor"); + +export const codecForExchangeHandle = (): Codec<ExchangeHandle> => +  makeCodecForObject<ExchangeHandle>() +    .property("master_pub", codecForString) +    .property("url", codecForString) +    .build("ExchangeHandle"); + +export const codecForAuditorHandle = (): Codec<AuditorHandle> => +  makeCodecForObject<AuditorHandle>() +    .property("name", codecForString) +    .property("master_pub", codecForString) +    .property("url", codecForString) +    .build("AuditorHandle"); + +export const codecForContractTerms = (): Codec<ContractTerms> => +  makeCodecForObject<ContractTerms>() +    .property("order_id", codecForString) +    .property("fulfillment_url", codecForString) +    .property("merchant_base_url", codecForString) +    .property("h_wire", codecForString) +    .property("auto_refund", makeCodecOptional(codecForDuration)) +    .property("wire_method", codecForString) +    .property("summary", codecForString) +    .property("nonce", codecForString) +    .property("amount", codecForString) +    .property("auditors", makeCodecForList(codecForAuditorHandle())) +    .property("pay_deadline", codecForTimestamp) +    .property("refund_deadline", codecForTimestamp) +    .property("wire_transfer_deadline", codecForTimestamp) +    .property("timestamp", codecForTimestamp) +    .property("locations", codecForAny) +    .property("max_fee", codecForString) +    .property("max_wire_fee", makeCodecOptional(codecForString)) +    .property("merchant", codecForAny) +    .property("merchant_pub", codecForString) +    .property("exchanges", makeCodecForList(codecForExchangeHandle())) +    .property("products", makeCodecOptional(makeCodecForList(codecForAny))) +    .property("extra", codecForAny) +    .build("ContractTerms"); + +export const codecForMerchantRefundPermission = (): Codec< +  MerchantRefundPermission +> => +  makeCodecForObject<MerchantRefundPermission>() +    .property("refund_amount", codecForString) +    .property("refund_fee", codecForString) +    .property("coin_pub", codecForString) +    .property("rtransaction_id", codecForNumber) +    .property("merchant_sig", codecForString) +    .build("MerchantRefundPermission"); + +export const codecForMerchantRefundResponse = (): Codec< +  MerchantRefundResponse +> => +  makeCodecForObject<MerchantRefundResponse>() +    .property("merchant_pub", codecForString) +    .property("h_contract_terms", codecForString) +    .property( +      "refund_permissions", +      makeCodecForList(codecForMerchantRefundPermission()), +    ) +    .build("MerchantRefundResponse"); + +export const codecForReserveSigSingleton = (): Codec<ReserveSigSingleton> => +  makeCodecForObject<ReserveSigSingleton>() +    .property("reserve_sig", codecForString) +    .build("ReserveSigSingleton"); + +export const codecForTipResponse = (): Codec<TipResponse> => +  makeCodecForObject<TipResponse>() +    .property("reserve_pub", codecForString) +    .property("reserve_sigs", makeCodecForList(codecForReserveSigSingleton())) +    .build("TipResponse"); + +export const codecForRecoup = (): Codec<Recoup> => +  makeCodecForObject<Recoup>() +    .property("h_denom_pub", codecForString) +    .build("Recoup"); + +export const codecForExchangeSigningKey = (): Codec<ExchangeSignKeyJson> => +  makeCodecForObject<ExchangeSignKeyJson>() +    .property("key", codecForString) +    .property("master_sig", codecForString) +    .property("stamp_end", codecForTimestamp) +    .property("stamp_start", codecForTimestamp) +    .property("stamp_expire", codecForTimestamp) +    .build("ExchangeSignKeyJson"); + +export const codecForExchangeKeysJson = (): Codec<ExchangeKeysJson> => +  makeCodecForObject<ExchangeKeysJson>() +    .property("denoms", makeCodecForList(codecForDenomination())) +    .property("master_public_key", codecForString) +    .property("auditors", makeCodecForList(codecForAuditor())) +    .property("list_issue_date", codecForTimestamp) +    .property("recoup", makeCodecOptional(makeCodecForList(codecForRecoup()))) +    .property("signkeys", makeCodecForList(codecForExchangeSigningKey())) +    .property("version", codecForString) +    .build("KeysJson"); + +export const codecForWireFeesJson = (): Codec<WireFeesJson> => +  makeCodecForObject<WireFeesJson>() +    .property("wire_fee", codecForString) +    .property("closing_fee", codecForString) +    .property("sig", codecForString) +    .property("start_date", codecForTimestamp) +    .property("end_date", codecForTimestamp) +    .build("WireFeesJson"); + +export const codecForAccountInfo = (): Codec<AccountInfo> => +  makeCodecForObject<AccountInfo>() +    .property("payto_uri", codecForString) +    .property("master_sig", codecForString) +    .build("AccountInfo"); + +export const codecForExchangeWireJson = (): Codec<ExchangeWireJson> => +  makeCodecForObject<ExchangeWireJson>() +    .property("accounts", makeCodecForList(codecForAccountInfo())) +    .property("fees", makeCodecForMap(makeCodecForList(codecForWireFeesJson()))) +    .build("ExchangeWireJson"); + +export const codecForProposal = (): Codec<Proposal> => +  makeCodecForObject<Proposal>() +    .property("contract_terms", codecForAny) +    .property("sig", codecForString) +    .build("Proposal"); + +export const codecForCheckPaymentResponse = (): Codec<CheckPaymentResponse> => +  makeCodecForObject<CheckPaymentResponse>() +    .property("paid", codecForBoolean) +    .property("refunded", makeCodecOptional(codecForBoolean)) +    .property("refunded_amount", makeCodecOptional(codecForString)) +    .property("contract_terms", makeCodecOptional(codecForAny)) +    .property("taler_pay_uri", makeCodecOptional(codecForString)) +    .property("contract_url", makeCodecOptional(codecForString)) +    .build("CheckPaymentResponse"); + +export const codecForWithdrawOperationStatusResponse = (): Codec< +  WithdrawOperationStatusResponse +> => +  makeCodecForObject<WithdrawOperationStatusResponse>() +    .property("selection_done", codecForBoolean) +    .property("transfer_done", codecForBoolean) +    .property("amount", codecForString) +    .property("sender_wire", makeCodecOptional(codecForString)) +    .property("suggested_exchange", makeCodecOptional(codecForString)) +    .property("confirm_transfer_url", makeCodecOptional(codecForString)) +    .property("wire_types", makeCodecForList(codecForString)) +    .build("WithdrawOperationStatusResponse"); + +export const codecForTipPickupGetResponse = (): Codec<TipPickupGetResponse> =>      makeCodecForObject<TipPickupGetResponse>()        .property("extra", codecForAny)        .property("amount", codecForString) @@ -1009,20 +970,15 @@ export const codecForTipPickupGetResponse = () =>        .property("exchange_url", codecForString)        .property("stamp_expire", codecForTimestamp)        .property("stamp_created", codecForTimestamp) -      .build("TipPickupGetResponse"), -  ); +      .build("TipPickupGetResponse"); -export const codecForRecoupConfirmation = () => -  typecheckedCodec<RecoupConfirmation>( +export const codecForRecoupConfirmation = (): Codec<RecoupConfirmation> =>      makeCodecForObject<RecoupConfirmation>()        .property("reserve_pub", makeCodecOptional(codecForString))        .property("old_coin_pub", makeCodecOptional(codecForString)) -      .build("RecoupConfirmation"), -  ); +      .build("RecoupConfirmation"); -export const codecForWithdrawResponse = () => -  typecheckedCodec<WithdrawResponse>( +export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>      makeCodecForObject<WithdrawResponse>()        .property("ev_sig", codecForString) -      .build("WithdrawResponse"), -  ); +      .build("WithdrawResponse"); diff --git a/src/types/walletTypes.ts b/src/types/walletTypes.ts index 5d28c5ae7..3d919c6f1 100644 --- a/src/types/walletTypes.ts +++ b/src/types/walletTypes.ts @@ -30,18 +30,16 @@  import { AmountJson, codecForAmountJson } from "../util/amounts";  import * as LibtoolVersion from "../util/libtoolVersion";  import { -  CoinRecord,    DenominationRecord,    ExchangeRecord,    ExchangeWireInfo,  } from "./dbTypes"; -import { CoinDepositPermission, ContractTerms } from "./talerTypes";  import { Timestamp } from "../util/time";  import { -  typecheckedCodec,    makeCodecForObject,    codecForString,    makeCodecOptional, +  Codec,  } from "../util/codec";  /** @@ -261,16 +259,14 @@ export interface CreateReserveRequest {    bankWithdrawStatusUrl?: string;  } -export const codecForCreateReserveRequest = () => -  typecheckedCodec<CreateReserveRequest>( +export const codecForCreateReserveRequest = (): Codec<CreateReserveRequest> =>      makeCodecForObject<CreateReserveRequest>()        .property("amount", codecForAmountJson())        .property("exchange", codecForString)        .property("exchangeWire", codecForString)        .property("senderWire", makeCodecOptional(codecForString))        .property("bankWithdrawStatusUrl", makeCodecOptional(codecForString)) -      .build("CreateReserveRequest"), -  ); +      .build("CreateReserveRequest");  /**   * Request to mark a reserve as confirmed. @@ -283,12 +279,10 @@ export interface ConfirmReserveRequest {    reservePub: string;  } -export const codecForConfirmReserveRequest = () => -  typecheckedCodec<ConfirmReserveRequest>( +export const codecForConfirmReserveRequest = (): Codec<ConfirmReserveRequest> =>      makeCodecForObject<ConfirmReserveRequest>()        .property("reservePub", codecForString) -      .build("ConfirmReserveRequest"), -  ); +      .build("ConfirmReserveRequest");  /**   * Wire coins to the user's own bank account. diff --git a/src/util/amounts.ts b/src/util/amounts.ts index f0a4f1d72..da1c19233 100644 --- a/src/util/amounts.ts +++ b/src/util/amounts.ts @@ -22,10 +22,10 @@   * Imports.   */  import { -  typecheckedCodec,    makeCodecForObject,    codecForString,    codecForNumber, +  Codec,  } from "./codec";  /** @@ -66,14 +66,12 @@ export interface AmountJson {    readonly currency: string;  } -export const codecForAmountJson = () => -  typecheckedCodec<AmountJson>( +export const codecForAmountJson = (): Codec<AmountJson> =>      makeCodecForObject<AmountJson>()        .property("currency", codecForString)        .property("value", codecForNumber)        .property("fraction", codecForNumber) -      .build("AmountJson"), -  ); +      .build("AmountJson");  /**   * Result of a possibly overflowing operation. @@ -100,7 +98,7 @@ export function getZero(currency: string): AmountJson {    };  } -export function sum(amounts: AmountJson[]) { +export function sum(amounts: AmountJson[]): Result {    if (amounts.length <= 0) {      throw Error("can't sum zero amounts");    } @@ -287,7 +285,7 @@ export function parseOrThrow(s: string): AmountJson {   * Convert a float to a Taler amount.   * Loss of precision possible.   */ -export function fromFloat(floatVal: number, currency: string) { +export function fromFloat(floatVal: number, currency: string): AmountJson {    return {      currency,      fraction: Math.floor((floatVal - Math.floor(floatVal)) * fractionalBase), diff --git a/src/util/asyncMemo.ts b/src/util/asyncMemo.ts index 84fe6b802..6e88081b6 100644 --- a/src/util/asyncMemo.ts +++ b/src/util/asyncMemo.ts @@ -24,7 +24,7 @@ export class AsyncOpMemoMap<T> {    private n = 0;    private memoMap: { [k: string]: MemoEntry<T> } = {}; -  private cleanUp(key: string, n: number) { +  private cleanUp(key: string, n: number): void {      const r = this.memoMap[key];      if (r && r.n === n) {        delete this.memoMap[key]; @@ -48,7 +48,7 @@ export class AsyncOpMemoMap<T> {        this.cleanUp(key, n);      });    } -  clear() { +  clear(): void {      this.memoMap = {};    }  } @@ -57,7 +57,7 @@ export class AsyncOpMemoSingle<T> {    private n = 0;    private memoEntry: MemoEntry<T> | undefined; -  private cleanUp(n: number) { +  private cleanUp(n: number): void {      if (this.memoEntry && this.memoEntry.n === n) {        this.memoEntry = undefined;      } @@ -81,7 +81,7 @@ export class AsyncOpMemoSingle<T> {      };      return p;    } -  clear() { +  clear(): void {      this.memoEntry = undefined;    }  } diff --git a/src/util/codec.ts b/src/util/codec.ts index a8f495238..480e1eec7 100644 --- a/src/util/codec.ts +++ b/src/util/codec.ts @@ -346,8 +346,4 @@ export function makeCodecOptional<V>(        return innerCodec.decode(x, c);      },    }; -} - -export function typecheckedCodec<T = undefined>(c: Codec<T>): Codec<T> { -  return c; -} +}
\ No newline at end of file diff --git a/src/util/http.ts b/src/util/http.ts index 1a5cb85fa..3842347dc 100644 --- a/src/util/http.ts +++ b/src/util/http.ts @@ -116,7 +116,7 @@ export class BrowserHttpLib implements HttpRequestLibrary {              );              return;            } -          const makeJson = async () => { +          const makeJson = async (): Promise<any> => {              let responseJson;              try {                responseJson = JSON.parse(myRequest.responseText); @@ -152,15 +152,15 @@ export class BrowserHttpLib implements HttpRequestLibrary {      });    } -  get(url: string, opt?: HttpRequestOptions) { +  get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {      return this.req("get", url, undefined, opt);    } -  postJson(url: string, body: any, opt?: HttpRequestOptions) { +  postJson(url: string, body: any, opt?: HttpRequestOptions): Promise<HttpResponse> {      return this.req("post", url, JSON.stringify(body), opt);    } -  stop() { +  stop(): void {      // Nothing to do    }  } diff --git a/src/util/logging.ts b/src/util/logging.ts index 80ba344d5..83e8d2192 100644 --- a/src/util/logging.ts +++ b/src/util/logging.ts @@ -24,7 +24,7 @@ function writeNodeLog(    tag: string,    level: string,    args: any[], -) { +): void {    process.stderr.write(`${new Date().toISOString()} ${tag} ${level} `);    process.stderr.write(message);    if (args.length != 0) { @@ -41,7 +41,7 @@ function writeNodeLog(  export class Logger {    constructor(private tag: string) {} -  info(message: string, ...args: any[]) { +  info(message: string, ...args: any[]): void {      if (isNode()) {        writeNodeLog(message, this.tag, "INFO", args);      } else { @@ -52,7 +52,7 @@ export class Logger {      }    } -  warn(message: string, ...args: any[]) { +  warn(message: string, ...args: any[]): void {      if (isNode()) {        writeNodeLog(message, this.tag, "WARN", args);      } else { @@ -63,7 +63,7 @@ export class Logger {      }    } -  error(message: string, ...args: any[]) { +  error(message: string, ...args: any[]): void {      if (isNode()) {        writeNodeLog(message, this.tag, "ERROR", args);      } else { @@ -74,7 +74,7 @@ export class Logger {      }    } -  trace(message: any, ...args: any[]) { +  trace(message: any, ...args: any[]): void {      if (isNode()) {        writeNodeLog(message, this.tag, "TRACE", args);      } else { diff --git a/src/util/query.ts b/src/util/query.ts index 44f668658..d11b79a96 100644 --- a/src/util/query.ts +++ b/src/util/query.ts @@ -26,6 +26,11 @@  import { openPromise } from "./promiseUtils";  /** + * Exception that should be thrown by client code to abort a transaction. + */ +export const TransactionAbort = Symbol("transaction_abort"); + +/**   * Definition of an object store.   */  export class Store<T> { @@ -430,11 +435,6 @@ export function openDatabase(    });  } -/** - * Exception that should be thrown by client code to abort a transaction. - */ -export const TransactionAbort = Symbol("transaction_abort"); -  export class Database {    constructor(private db: IDBDatabase) {} diff --git a/src/util/time.ts b/src/util/time.ts index 05188b6d2..ea4f8ca8d 100644 --- a/src/util/time.ts +++ b/src/util/time.ts @@ -36,7 +36,7 @@ export interface Duration {  let timeshift = 0; -export function setDangerousTimetravel(dt: number) { +export function setDangerousTimetravel(dt: number): void {    timeshift = dt;  } @@ -121,7 +121,7 @@ export function timestampSubtractDuraction(    return { t_ms: Math.max(0, t1.t_ms - d.d_ms) };  } -export function stringifyTimestamp(t: Timestamp) { +export function stringifyTimestamp(t: Timestamp): string {    if (t.t_ms === "never") {      return "never";    } @@ -142,7 +142,7 @@ export function timestampIsBetween(    t: Timestamp,    start: Timestamp,    end: Timestamp, -) { +): boolean {    if (timestampCmp(t, start) < 0) {      return false;    } diff --git a/src/wallet-test.ts b/src/wallet-test.ts index d1551b09f..422523665 100644 --- a/src/wallet-test.ts +++ b/src/wallet-test.ts @@ -16,9 +16,6 @@  import test from "ava"; -import * as dbTypes from "./types/dbTypes"; -import * as types from "./types/walletTypes"; -  import { AmountJson } from "./util/amounts";  import * as Amounts from "./util/amounts";  import { selectPayCoins, AvailableCoinInfo } from "./operations/pay"; diff --git a/src/wallet.ts b/src/wallet.ts index 063a259d6..02450523e 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -47,7 +47,6 @@ import {    CurrencyRecord,    DenominationRecord,    ExchangeRecord, -  ProposalRecord,    PurchaseRecord,    ReserveRecord,    Stores, @@ -155,7 +154,7 @@ export class Wallet {      this.ws = new InternalWalletState(db, http, cryptoWorkerFactory);    } -  getExchangePaytoUri(exchangeBaseUrl: string, supportedTargetTypes: string[]) { +  getExchangePaytoUri(exchangeBaseUrl: string, supportedTargetTypes: string[]): Promise<string> {      return getExchangePaytoUri(this.ws, exchangeBaseUrl, supportedTargetTypes);    } @@ -371,7 +370,7 @@ export class Wallet {     * auditors into the database, unless these defaults have     * already been applied.     */ -  async fillDefaults() { +  async fillDefaults(): Promise<void> {      await this.db.runWithWriteTransaction(        [Stores.config, Stores.currencies],        async (tx) => { @@ -549,7 +548,7 @@ export class Wallet {    async acceptExchangeTermsOfService(      exchangeBaseUrl: string,      etag: string | undefined, -  ) { +  ): Promise<void> {      return acceptExchangeTermsOfService(this.ws, exchangeBaseUrl, etag);    } @@ -596,7 +595,7 @@ export class Wallet {    /**     * Stop ongoing processing.     */ -  stop() { +  stop(): void {      this.stopped = true;      this.timerGroup.stopCurrentAndFutureTimers();      this.ws.cryptoApi.stop(); @@ -685,7 +684,7 @@ export class Wallet {     * Inform the wallet that the status of a reserve has changed (e.g. due to a     * confirmation from the bank.).     */ -  public async handleNotifyReserve() { +  public async handleNotifyReserve(): Promise<void> {      const reserves = await this.db.iter(Stores.reserves).toArray();      for (const r of reserves) {        if (r.reserveStatus === ReserveRecordStatus.WAIT_CONFIRM_BANK) { @@ -702,7 +701,7 @@ export class Wallet {     * Remove unreferenced / expired data from the wallet's database     * based on the current system time.     */ -  async collectGarbage() { +  async collectGarbage(): Promise<void> {      // FIXME(#5845)      // We currently do not garbage-collect the wallet database.  This might change      // after the feature has been properly re-designed, and we have come up with a diff --git a/src/webex/chromeBadge.ts b/src/webex/chromeBadge.ts index 330388ca0..7bc5d368d 100644 --- a/src/webex/chromeBadge.ts +++ b/src/webex/chromeBadge.ts @@ -20,7 +20,7 @@ import { isFirefox } from "./compat";   * Polyfill for requestAnimationFrame, which   * doesn't work from a background page.   */ -function rAF(cb: (ts: number) => void) { +function rAF(cb: (ts: number) => void): void {    window.setTimeout(() => {      cb(performance.now());    }, 100 /* 100 ms delay between frames */); @@ -99,14 +99,18 @@ export class ChromeBadge {      // size in draw() as well!      this.canvas.width = 32;      this.canvas.height = 32; -    this.ctx = this.canvas.getContext("2d")!; +    const ctx = this.canvas.getContext("2d"); +    if (!ctx) { +      throw Error("unable to get canvas context"); +    } +    this.ctx = ctx;      this.draw();    }    /**     * Draw the badge based on the current state.     */ -  private draw() { +  private draw(): void {      this.ctx.setTransform(1, 0, 0, 1, 0, 0);      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); @@ -202,7 +206,7 @@ export class ChromeBadge {      }    } -  private animate() { +  private animate(): void {      if (this.animationRunning) {        return;      } @@ -212,7 +216,7 @@ export class ChromeBadge {      }      this.animationRunning = true;      let start: number | undefined; -    const step = (timestamp: number) => { +    const step = (timestamp: number): void => {        if (!this.animationRunning) {          return;        } @@ -257,7 +261,7 @@ export class ChromeBadge {     * Draw the badge such that it shows the     * user that something happened (balance changed).     */ -  showNotification() { +  showNotification(): void {      this.hasNotification = true;      this.draw();    } @@ -265,12 +269,12 @@ export class ChromeBadge {    /**     * Draw the badge without the notification mark.     */ -  clearNotification() { +  clearNotification(): void {      this.hasNotification = false;      this.draw();    } -  startBusy() { +  startBusy(): void {      if (this.isBusy) {        return;      } @@ -278,7 +282,7 @@ export class ChromeBadge {      this.animate();    } -  stopBusy() { +  stopBusy(): void {      this.isBusy = false;    }  } diff --git a/src/webex/notify.ts b/src/webex/notify.ts index 887658ef9..9fb0529db 100644 --- a/src/webex/notify.ts +++ b/src/webex/notify.ts @@ -47,7 +47,7 @@ const handlers: Handler[] = [];  let sheet: CSSStyleSheet | null; -function initStyle() { +function initStyle(): void {    logVerbose && console.log("taking over styles");    const name = "taler-presence-stylesheet";    const content = "/* Taler stylesheet controlled by JS */"; @@ -78,7 +78,7 @@ function initStyle() {    }  } -function setStyles(installed: boolean) { +function setStyles(installed: boolean): void {    if (!sheet || !sheet.cssRules) {      return;    } @@ -93,7 +93,7 @@ function setStyles(installed: boolean) {    }  } -function onceOnComplete(cb: () => void) { +function onceOnComplete(cb: () => void): void {    if (document.readyState === "complete") {      cb();    } else { @@ -105,7 +105,7 @@ function onceOnComplete(cb: () => void) {    }  } -function init() { +function init(): void {    onceOnComplete(() => {      if (document.documentElement.getAttribute("data-taler-nojs")) {        initStyle(); @@ -129,13 +129,13 @@ function init() {  type HandlerFn = (detail: any, sendResponse: (msg: any) => void) => void; -function registerHandlers() { +function registerHandlers(): void {    /**     * Add a handler for a DOM event, which automatically     * handles adding sequence numbers to responses.     */ -  function addHandler(type: string, handler: HandlerFn) { -    const handlerWrap = (e: Event) => { +  function addHandler(type: string, handler: HandlerFn): void { +    const handlerWrap = (e: Event): void => {        if (!(e instanceof Event)) {          console.log("unexpected event", e);          throw Error(`invariant violated`); @@ -154,7 +154,7 @@ function registerHandlers() {          callId = e.detail.callId;          detail = e.detail;        } -      const responder = (msg?: any) => { +      const responder = (msg?: any): void => {          const fullMsg = Object.assign({}, msg, { callId });          let opts = { detail: fullMsg };          if ("function" === typeof cloneInto) { diff --git a/src/webex/pages/add-auditor.tsx b/src/webex/pages/add-auditor.tsx index dbe84cde4..4e3f8615c 100644 --- a/src/webex/pages/add-auditor.tsx +++ b/src/webex/pages/add-auditor.tsx @@ -31,10 +31,10 @@ interface ConfirmAuditorProps {    expirationStamp: number;  } -function ConfirmAuditor(props: ConfirmAuditorProps) { +function ConfirmAuditor(props: ConfirmAuditorProps): JSX.Element {    const [addDone, setAddDone] = useState(false); -  const add = async () => { +  const add = async (): Promise<void> => {      const currencies = await getCurrencies();      let currency: CurrencyRecord | undefined; diff --git a/src/webex/pages/benchmark.tsx b/src/webex/pages/benchmark.tsx index bf4c4b04d..eb7193e0c 100644 --- a/src/webex/pages/benchmark.tsx +++ b/src/webex/pages/benchmark.tsx @@ -34,7 +34,7 @@ interface BenchmarkRunnerState {    running: boolean;  } -function BenchmarkDisplay(props: BenchmarkRunnerState) { +function BenchmarkDisplay(props: BenchmarkRunnerState): JSX.Element {    const result = props.result;    if (!result) {      if (props.running) { @@ -55,7 +55,7 @@ function BenchmarkDisplay(props: BenchmarkRunnerState) {            {Object.keys(result.time)              .sort()              .map((k) => ( -              <tr> +              <tr key={k}>                  <td>{k}</td>                  <td>{result.time[k] / result.repetitions}</td>                </tr> @@ -75,13 +75,13 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {      };    } -  async run() { +  async run(): Promise<void> {      this.setState({ result: undefined, running: true });      const result = await wxApi.benchmarkCrypto(this.state.repetitions);      this.setState({ result, running: false });    } -  render() { +  render(): JSX.Element {      return (        <div>          <label>Repetitions:</label> @@ -99,6 +99,6 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {    }  } -export function makeBenchmarkPage() { +export function makeBenchmarkPage(): JSX.Element {    return <BenchmarkRunner />;  } diff --git a/src/webex/pages/pay.tsx b/src/webex/pages/pay.tsx index 09aa595c3..e3dd630b6 100644 --- a/src/webex/pages/pay.tsx +++ b/src/webex/pages/pay.tsx @@ -34,7 +34,7 @@ import React, { useState, useEffect } from "react";  import * as Amounts from "../../util/amounts";  import { codecForContractTerms, ContractTerms } from "../../types/talerTypes"; -function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { +function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {    const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>();    const [payErrMsg, setPayErrMsg] = useState<string | undefined>("");    const [numTries, setNumTries] = useState(0); @@ -42,7 +42,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {    let totalFees: Amounts.AmountJson | undefined = undefined;    useEffect(() => { -    const doFetch = async () => { +    const doFetch = async (): Promise<void> => {        const p = await wxApi.preparePay(talerPayUri);        setPayStatus(p);      }; @@ -108,7 +108,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {      <strong>{renderAmount(Amounts.parseOrThrow(contractTerms.amount))}</strong>    ); -  const doPayment = async () => { +  const doPayment = async (): Promise<void> => {      if (payStatus.status !== "payment-possible") {        throw Error(`invalid state: ${payStatus.status}`);      } @@ -178,11 +178,11 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {    );  } -export function makePayPage() { +export function makePayPage(): JSX.Element {    const url = new URL(document.location.href);    const talerPayUri = url.searchParams.get("talerPayUri");    if (!talerPayUri) {      throw Error("invalid parameter");    }    return <TalerPayDialog talerPayUri={talerPayUri} />; -}
\ No newline at end of file +} diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx index 6cd7242ff..c2f050e2a 100644 --- a/src/webex/pages/popup.tsx +++ b/src/webex/pages/popup.tsx @@ -46,7 +46,7 @@ import { Timestamp } from "../../util/time";  function onUpdateNotification(f: () => void): () => void {    const port = chrome.runtime.connect({ name: "notifications" }); -  const listener = () => { +  const listener = (): void => {      f();    };    port.onMessage.addListener(listener); @@ -75,7 +75,7 @@ class Router extends React.Component<any, any> {    private static routeHandlers: any[] = []; -  componentWillMount() { +  componentWillMount(): void {      console.log("router mounted");      window.onhashchange = () => {        this.setState({}); @@ -85,10 +85,6 @@ class Router extends React.Component<any, any> {      };    } -  componentWillUnmount() { -    console.log("router unmounted"); -  } -    render(): JSX.Element {      const route = window.location.hash.substring(1);      console.log("rendering route", route); @@ -120,12 +116,12 @@ interface TabProps {    children?: React.ReactNode;  } -function Tab(props: TabProps) { +function Tab(props: TabProps): JSX.Element {    let cssClass = "";    if (props.target === Router.getRoute()) {      cssClass = "active";    } -  const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => { +  const onClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {      Router.setRoute(props.target);      e.preventDefault();    }; @@ -139,19 +135,19 @@ function Tab(props: TabProps) {  class WalletNavBar extends React.Component<any, any> {    private cancelSubscription: any; -  componentWillMount() { +  componentWillMount(): void {      this.cancelSubscription = Router.onRoute(() => {        this.setState({});      });    } -  componentWillUnmount() { +  componentWillUnmount(): void {      if (this.cancelSubscription) {        this.cancelSubscription();      }    } -  render() { +  render(): JSX.Element {      console.log("rendering nav bar");      return (        <div className="nav" id="header"> @@ -163,20 +159,6 @@ class WalletNavBar extends React.Component<any, any> {    }  } -function ExtensionLink(props: any) { -  const onClick = (e: React.MouseEvent<HTMLAnchorElement>) => { -    chrome.tabs.create({ -      url: chrome.extension.getURL(props.target), -    }); -    e.preventDefault(); -  }; -  return ( -    <a onClick={onClick} href={props.target}> -      {props.children} -    </a> -  ); -} -  /**   * Render an amount as a large number with a small currency symbol.   */ @@ -190,7 +172,7 @@ function bigAmount(amount: AmountJson): JSX.Element {    );  } -function EmptyBalanceView() { +function EmptyBalanceView(): JSX.Element {    return (      <i18n.Translate wrap="p">        You have no balance to show. Need some{" "} @@ -205,12 +187,12 @@ class WalletBalanceView extends React.Component<any, any> {    private canceler: (() => void) | undefined = undefined;    private unmount = false; -  componentWillMount() { +  componentWillMount(): void {      this.canceler = onUpdateNotification(() => this.updateBalance());      this.updateBalance();    } -  componentWillUnmount() { +  componentWillUnmount(): void {      console.log("component WalletBalanceView will unmount");      if (this.canceler) {        this.canceler(); @@ -218,7 +200,7 @@ class WalletBalanceView extends React.Component<any, any> {      this.unmount = true;    } -  async updateBalance() { +  async updateBalance(): Promise<void> {      let balance: WalletBalance;      try {        balance = await wxApi.getBalance(); @@ -325,11 +307,11 @@ class WalletBalanceView extends React.Component<any, any> {    }  } -function Icon({ l }: { l: string }) { +function Icon({ l }: { l: string }): JSX.Element {    return <div className={"icon"}>{l}</div>;  } -function formatAndCapitalize(text: string) { +function formatAndCapitalize(text: string): string {    text = text.replace("-", " ");    text = text.replace(/^./, text[0].toUpperCase());    return text; @@ -357,8 +339,8 @@ function HistoryItem({    timestamp,    icon,    negative = false, -}: HistoryItemProps) { -  function formatDate(timestamp: number | "never") { +}: HistoryItemProps): JSX.Element { +  function formatDate(timestamp: number | "never"): string | null {      if (timestamp !== "never") {        const itemDate = moment(timestamp);        if (itemDate.isBetween(moment().subtract(2, "days"), moment())) { @@ -444,7 +426,7 @@ function parseSummary(summary: string) {    };  } -function formatHistoryItem(historyItem: HistoryEvent) { +function formatHistoryItem(historyItem: HistoryEvent): JSX.Element {    switch (historyItem.type) {      case "refreshed": {        return ( @@ -637,7 +619,7 @@ function formatHistoryItem(historyItem: HistoryEvent) {    }  } -const HistoryComponent = (props: any) => { +const HistoryComponent = (props: any): JSX.Element => {    const record = props.record;    return formatHistoryItem(record);  }; @@ -655,18 +637,18 @@ class WalletHistory extends React.Component<any, any> {      "exchange-added",    ]; -  componentWillMount() { +  componentWillMount(): void {      this.update();      this.setState({ filter: true });      onUpdateNotification(() => this.update());    } -  componentWillUnmount() { +  componentWillUnmount(): void {      console.log("history component unmounted");      this.unmounted = true;    } -  update() { +  update(): void {      chrome.runtime.sendMessage({ type: "get-history" }, (resp) => {        if (this.unmounted) {          return; @@ -727,7 +709,7 @@ class WalletHistory extends React.Component<any, any> {    }  } -function reload() { +function reload(): void {    try {      chrome.runtime.reload();      window.close(); @@ -736,7 +718,7 @@ function reload() {    }  } -function confirmReset() { +function confirmReset(): void {    if (      confirm(        "Do you want to IRREVOCABLY DESTROY everything inside your" + @@ -748,7 +730,7 @@ function confirmReset() {    }  } -function WalletDebug(props: any) { +function WalletDebug(props: any): JSX.Element {    return (      <div>        <p>Debug tools:</p> @@ -791,7 +773,7 @@ function openTab(page: string) {    };  } -function WalletPopup() { +function WalletPopup(): JSX.Element {    return (      <div>        <WalletNavBar /> @@ -806,7 +788,7 @@ function WalletPopup() {    );  } -export function createPopup() { +export function createPopup(): JSX.Element {    chrome.runtime.connect({ name: "popup" });    return <WalletPopup />;  }
\ No newline at end of file diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx index 8263ceace..4a13317cd 100644 --- a/src/webex/pages/refund.tsx +++ b/src/webex/pages/refund.tsx @@ -21,13 +21,12 @@   */  import React, { useEffect, useState } from "react"; -import ReactDOM from "react-dom";  import * as wxApi from "../wxApi";  import { PurchaseDetails } from "../../types/walletTypes";  import { AmountView } from "../renderHtml"; -function RefundStatusView(props: { talerRefundUri: string }) { +function RefundStatusView(props: { talerRefundUri: string }): JSX.Element {    const [applied, setApplied] = useState(false);    const [purchaseDetails, setPurchaseDetails] = useState<      PurchaseDetails | undefined @@ -35,7 +34,7 @@ function RefundStatusView(props: { talerRefundUri: string }) {    const [errMsg, setErrMsg] = useState<string | undefined>(undefined);    useEffect(() => { -    const doFetch = async () => { +    const doFetch = async (): Promise<void> => {        try {          const hc = await wxApi.applyRefund(props.talerRefundUri);          setApplied(true); @@ -73,19 +72,17 @@ function RefundStatusView(props: { talerRefundUri: string }) {    );  } -export function createRefundPage() { +export function createRefundPage(): JSX.Element {    const url = new URL(document.location.href);    const container = document.getElementById("container");    if (!container) { -    console.error("fatal: can't mount component, container missing"); -    return; +    throw Error("fatal: can't mount component, container missing")    }    const talerRefundUri = url.searchParams.get("talerRefundUri");    if (!talerRefundUri) { -    console.error("taler refund URI requred"); -    return; +    throw Error("taler refund URI requred");    }    return <RefundStatusView talerRefundUri={talerRefundUri} />; diff --git a/src/webex/pages/return-coins.tsx b/src/webex/pages/return-coins.tsx index 06a3ba169..7d759705f 100644 --- a/src/webex/pages/return-coins.tsx +++ b/src/webex/pages/return-coins.tsx @@ -38,7 +38,6 @@ import { getBalance, getSenderWireInfos, returnCoins } from "../wxApi";  import { renderAmount } from "../renderHtml";  import * as React from "react"; -import * as ReactDOM from "react-dom";  interface ReturnSelectionItemProps extends ReturnSelectionListProps {    exchangeUrl: string; @@ -129,7 +128,7 @@ class ReturnSelectionItem extends React.Component<      );    } -  select() { +  select(): void {      let val: number;      let selectedWire: number;      try { @@ -188,7 +187,7 @@ interface ReturnConfirmationProps {  }  class ReturnConfirmation extends React.Component<ReturnConfirmationProps, {}> { -  render() { +  render(): JSX.Element {      return (        <div>          <p> @@ -238,7 +237,7 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {      this.state = {} as any;    } -  async update() { +  async update(): Promise<void> {      const balance = await getBalance();      const senderWireInfos = await getSenderWireInfos();      console.log("got swi", senderWireInfos); @@ -246,11 +245,11 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {      this.setState({ balance, senderWireInfos });    } -  selectDetail(d: SelectedDetail) { +  selectDetail(d: SelectedDetail): void {      this.setState({ selectedReturn: d });    } -  async confirm() { +  async confirm(): Promise<void> {      const selectedReturn = this.state.selectedReturn;      if (!selectedReturn) {        return; @@ -263,14 +262,14 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {      });    } -  async cancel() { +  async cancel(): Promise<void> {      this.setState({        selectedReturn: undefined,        lastConfirmedDetail: undefined,      });    } -  render() { +  render(): JSX.Element {      const balance = this.state.balance;      const senderWireInfos = this.state.senderWireInfos;      if (!balance || !senderWireInfos) { @@ -310,6 +309,6 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> {    }  } -export function createReturnCoinsPage() { +export function createReturnCoinsPage(): JSX.Element {    return <ReturnCoins />;  } diff --git a/src/webex/pages/tip.tsx b/src/webex/pages/tip.tsx index 10e12d590..9c797f50d 100644 --- a/src/webex/pages/tip.tsx +++ b/src/webex/pages/tip.tsx @@ -22,30 +22,25 @@   */  import * as React from "react"; -import * as ReactDOM from "react-dom"; -import * as i18n from "../i18n"; - -import { acceptTip, getReserveCreationInfo, getTipStatus } from "../wxApi"; +import { acceptTip, getTipStatus } from "../wxApi";  import { -  WithdrawDetailView,    renderAmount,    ProgressButton,  } from "../renderHtml"; -import * as Amounts from "../../util/amounts";  import { useState, useEffect } from "react";  import { TipStatus } from "../../types/walletTypes"; -function TipDisplay(props: { talerTipUri: string }) { +function TipDisplay(props: { talerTipUri: string }): JSX.Element {    const [tipStatus, setTipStatus] = useState<TipStatus | undefined>(undefined);    const [discarded, setDiscarded] = useState(false);    const [loading, setLoading] = useState(false);    const [finished, setFinished] = useState(false);    useEffect(() => { -    const doFetch = async () => { +    const doFetch = async (): Promise<void> => {        const ts = await getTipStatus(props.talerTipUri);        setTipStatus(ts);      }; @@ -53,7 +48,7 @@ function TipDisplay(props: { talerTipUri: string }) {    }, []);    if (discarded) { -    return <span>You've discarded the tip.</span>; +    return <span>You've discarded the tip.</span>;    }    if (finished) { @@ -64,11 +59,11 @@ function TipDisplay(props: { talerTipUri: string }) {      return <span>Loading ...</span>;    } -  const discard = () => { +  const discard = (): void => {      setDiscarded(true);    }; -  const accept = async () => { +  const accept = async (): Promise<void> => {      setLoading(true);      await acceptTip(tipStatus.tipId);      setFinished(true); @@ -100,7 +95,7 @@ function TipDisplay(props: { talerTipUri: string }) {    );  } -export function createTipPage() { +export function createTipPage(): JSX.Element {      const url = new URL(document.location.href);      const talerTipUri = url.searchParams.get("talerTipUri");      if (typeof talerTipUri !== "string") { diff --git a/src/webex/pages/welcome.tsx b/src/webex/pages/welcome.tsx index 8510ad383..a99cadb05 100644 --- a/src/webex/pages/welcome.tsx +++ b/src/webex/pages/welcome.tsx @@ -25,7 +25,7 @@ import { getDiagnostics } from "../wxApi";  import { PageLink } from "../renderHtml";  import { WalletDiagnostics } from "../../types/walletTypes"; -function Diagnostics() { +function Diagnostics(): JSX.Element {    const [timedOut, setTimedOut] = useState(false);    const [diagnostics, setDiagnostics] = useState<WalletDiagnostics | undefined>(      undefined, @@ -39,7 +39,7 @@ function Diagnostics() {          setTimedOut(true);        }      }, 1000); -    const doFetch = async () => { +    const doFetch = async (): Promise<void> => {        const d = await getDiagnostics();        console.log("got diagnostics", d);        gotDiagnostics = true; @@ -95,7 +95,7 @@ function Diagnostics() {    return <p>Running diagnostics ...</p>;  } -function Welcome() { +function Welcome(): JSX.Element {    return (      <>        <p>Thank you for installing the wallet.</p> @@ -110,6 +110,6 @@ function Welcome() {    );  } -export function createWelcomePage() { +export function createWelcomePage(): JSX.Element {    return <Welcome />;  }
\ No newline at end of file diff --git a/src/webex/pages/withdraw.tsx b/src/webex/pages/withdraw.tsx index e071dc8ba..9020ddb0b 100644 --- a/src/webex/pages/withdraw.tsx +++ b/src/webex/pages/withdraw.tsx @@ -28,10 +28,9 @@ import { WithdrawDetails } from "../../types/walletTypes";  import { WithdrawDetailView, renderAmount } from "../renderHtml";  import React, { useState, useEffect } from "react"; -import * as ReactDOM from "react-dom";  import { getWithdrawDetails, acceptWithdrawal } from "../wxApi"; -function NewExchangeSelection(props: { talerWithdrawUri: string }) { +function NewExchangeSelection(props: { talerWithdrawUri: string }): JSX.Element {    const [details, setDetails] = useState<WithdrawDetails | undefined>();    const [selectedExchange, setSelectedExchange] = useState<      string | undefined @@ -43,7 +42,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {    const [errMsg, setErrMsg] = useState<string | undefined>("");    useEffect(() => { -    const fetchData = async () => { +    const fetchData = async (): Promise<void> => {        console.log("getting from", talerWithdrawUri);        let d: WithdrawDetails | undefined = undefined;        try { @@ -145,7 +144,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {      );    } -  const accept = async () => { +  const accept = async (): Promise<void> => {      console.log("accepting exchange", selectedExchange);      const res = await acceptWithdrawal(talerWithdrawUri, selectedExchange!);      console.log("accept withdrawal response", res); @@ -197,27 +196,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {    );  } -async function main() { -  try { -    const url = new URL(document.location.href); -    const talerWithdrawUri = url.searchParams.get("talerWithdrawUri"); -    if (!talerWithdrawUri) { -      throw Error("withdraw URI required"); -    } - -    ReactDOM.render( -      <NewExchangeSelection talerWithdrawUri={talerWithdrawUri} />, -      document.getElementById("exchange-selection")!, -    ); -  } catch (e) { -    // TODO: provide more context information, maybe factor it out into a -    // TODO:generic error reporting function or component. -    document.body.innerText = i18n.str`Fatal error: "${e.message}".`; -    console.error("got error", e); -  } -} - -export function createWithdrawPage() { +export function createWithdrawPage(): JSX.Element {    const url = new URL(document.location.href);      const talerWithdrawUri = url.searchParams.get("talerWithdrawUri");      if (!talerWithdrawUri) { diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx index b6ff1248c..8fc6a6a63 100644 --- a/src/webex/renderHtml.tsx +++ b/src/webex/renderHtml.tsx @@ -29,14 +29,13 @@ import { DenominationRecord } from "../types/dbTypes";  import { ExchangeWithdrawDetails } from "../types/walletTypes";  import * as i18n from "./i18n";  import React from "react"; -import ReactDOM from "react-dom";  import { stringifyTimestamp } from "../util/time";  /**   * Render amount as HTML, which non-breaking space between   * decimal value and currency.   */ -export function renderAmount(amount: AmountJson | string) { +export function renderAmount(amount: AmountJson | string): JSX.Element {    let a;    if (typeof amount === "string") {      a = Amounts.parse(amount); @@ -54,14 +53,17 @@ export function renderAmount(amount: AmountJson | string) {    );  } -export const AmountView = ({ amount }: { amount: AmountJson | string }) => -  renderAmount(amount); +export const AmountView = ({ +  amount, +}: { +  amount: AmountJson | string; +}): JSX.Element => renderAmount(amount);  /**   * Abbreviate a string to a given length, and show the full   * string on hover as a tooltip.   */ -export function abbrev(s: string, n = 5) { +export function abbrev(s: string, n = 5): JSX.Element {    let sAbbrev = s;    if (s.length > n) {      sAbbrev = s.slice(0, n) + ".."; @@ -94,12 +96,12 @@ export class Collapsible extends React.Component<      super(props);      this.state = { collapsed: props.initiallyCollapsed };    } -  render() { -    const doOpen = (e: any) => { +  render(): JSX.Element { +    const doOpen = (e: any): void => {        this.setState({ collapsed: false });        e.preventDefault();      }; -    const doClose = (e: any) => { +    const doClose = (e: any): void => {        this.setState({ collapsed: true });        e.preventDefault();      }; @@ -188,7 +190,7 @@ function FeeDetailsView(props: {      countByPub[x.denomPub] = c;    }); -  function row(denom: DenominationRecord) { +  function row(denom: DenominationRecord): JSX.Element {      return (        <tr>          <td>{countByPub[denom.denomPub] + "x"}</td> @@ -296,7 +298,7 @@ interface ExpanderTextProps {  /**   * Show a heading with a toggle to show/hide the expandable content.   */ -export function ExpanderText({ text }: ExpanderTextProps) { +export function ExpanderText({ text }: ExpanderTextProps): JSX.Element {    return <span>{text}</span>;  } @@ -310,7 +312,7 @@ export function ProgressButton(        React.ButtonHTMLAttributes<HTMLButtonElement>,        HTMLButtonElement      >, -) { +): JSX.Element {    return (      <button        className="pure-button pure-button-primary" @@ -330,7 +332,9 @@ export function ProgressButton(    );  } -export function PageLink(props: React.PropsWithChildren<{ pageName: string }>) { +export function PageLink( +  props: React.PropsWithChildren<{ pageName: string }>, +): JSX.Element {    const url = chrome.extension.getURL(`/src/webex/pages/${props.pageName}`);    return (      <a className="actionLink" href={url} target="_blank"> diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts index a530b7506..07b223c87 100644 --- a/src/webex/wxApi.ts +++ b/src/webex/wxApi.ts @@ -38,6 +38,9 @@ import {    WalletBalance,    PurchaseDetails,    WalletDiagnostics, +  WithdrawDetails, +  PreparePayResult, +  AcceptWithdrawalResponse,  } from "../types/walletTypes";  import { MessageMap, MessageType } from "./messages"; @@ -271,7 +274,7 @@ export function applyRefund(refundUrl: string): Promise<string> {  /**   * Abort a failed payment and try to get a refund.   */ -export function abortFailedPayment(contractTermsHash: string) { +export function abortFailedPayment(contractTermsHash: string): Promise<void> {    return callBackend("abort-failed-payment", { contractTermsHash });  } @@ -288,7 +291,7 @@ export function benchmarkCrypto(repetitions: number): Promise<BenchmarkResult> {  export function getWithdrawDetails(    talerWithdrawUri: string,    maybeSelectedExchange: string | undefined, -) { +): Promise<WithdrawDetails> {    return callBackend("get-withdraw-details", {      talerWithdrawUri,      maybeSelectedExchange, @@ -298,7 +301,7 @@ export function getWithdrawDetails(  /**   * Get details about a pay operation.   */ -export function preparePay(talerPayUri: string) { +export function preparePay(talerPayUri: string): Promise<PreparePayResult> {    return callBackend("prepare-pay", { talerPayUri });  } @@ -308,7 +311,7 @@ export function preparePay(talerPayUri: string) {  export function acceptWithdrawal(    talerWithdrawUri: string,    selectedExchange: string, -) { +): Promise<AcceptWithdrawalResponse> {    return callBackend("accept-withdrawal", {      talerWithdrawUri,      selectedExchange, diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts index ef4715dce..f26c14d37 100644 --- a/src/webex/wxBackend.ts +++ b/src/webex/wxBackend.ts @@ -40,7 +40,6 @@ import { BrowserHttpLib } from "../util/http";  import { OpenedPromise, openPromise } from "../util/promiseUtils";  import { classifyTalerUri, TalerUriType } from "../util/taleruri";  import { Wallet } from "../wallet"; -import { ChromeBadge } from "./chromeBadge";  import { isFirefox } from "./compat";  import { MessageType } from "./messages";  import * as wxApi from "./wxApi"; @@ -49,6 +48,21 @@ import { Database } from "../util/query";  const NeedsWallet = Symbol("NeedsWallet"); +/** + * Currently active wallet instance.  Might be unloaded and + * re-instantiated when the database is reset. + */ +let currentWallet: Wallet | undefined; + +let currentDatabase: IDBDatabase | undefined; + +/** + * Last version if an outdated DB, if applicable. + */ +let outdatedDbVersion: number | undefined; + +const walletInit: OpenedPromise<void> = openPromise<void>(); +  async function handleMessage(    sender: MessageSender,    type: MessageType, @@ -57,14 +71,12 @@ async function handleMessage(    function assertNotFound(t: never): never {      console.error(`Request type ${t as string} unknown`);      console.error(`Request detail was ${detail}`); -    return ( -      { -        error: { -          message: `request type ${t as string} unknown`, -          requestType: type, -        }, -      } as never -    ); +    return { +      error: { +        message: `request type ${t as string} unknown`, +        requestType: type, +      }, +    } as never;    }    function needsWallet(): Wallet {      if (!currentWallet) { @@ -320,7 +332,7 @@ function getTab(tabId: number): Promise<chrome.tabs.Tab> {    });  } -function setBadgeText(options: chrome.browserAction.BadgeTextDetails) { +function setBadgeText(options: chrome.browserAction.BadgeTextDetails): void {    // not supported by all browsers ...    if (chrome && chrome.browserAction && chrome.browserAction.setBadgeText) {      chrome.browserAction.setBadgeText(options); @@ -331,9 +343,12 @@ function setBadgeText(options: chrome.browserAction.BadgeTextDetails) {  function waitMs(timeoutMs: number): Promise<void> {    return new Promise((resolve, reject) => { -    chrome.extension -      .getBackgroundPage()! -      .setTimeout(() => resolve(), timeoutMs); +    const bgPage = chrome.extension.getBackgroundPage(); +    if (!bgPage) { +      reject("fatal: no background page"); +      return; +    } +    bgPage.setTimeout(() => resolve(), timeoutMs);    });  } @@ -359,7 +374,7 @@ function makeSyncWalletRedirect(    if (isFirefox()) {      // Some platforms don't support the sync redirect (yet), so fall back to      // async redirect after a timeout. -    const doit = async () => { +    const doit = async (): Promise<void> => {        await waitMs(150);        const tab = await getTab(tabId);        if (tab.url === oldUrl) { @@ -371,29 +386,13 @@ function makeSyncWalletRedirect(    return { redirectUrl: outerUrl.href };  } -/** - * Currently active wallet instance.  Might be unloaded and - * re-instantiated when the database is reset. - */ -let currentWallet: Wallet | undefined; - -let currentDatabase: IDBDatabase | undefined; - -/** - * Last version if an outdated DB, if applicable. - */ -let outdatedDbVersion: number | undefined; - -const walletInit: OpenedPromise<void> = openPromise<void>(); - -async function reinitWallet() { +async function reinitWallet(): Promise<void> {    if (currentWallet) {      currentWallet.stop();      currentWallet = undefined;    }    currentDatabase = undefined;    setBadgeText({ text: "" }); -  const badge = new ChromeBadge();    try {      currentDatabase = await openTalerDatabase(indexedDB, reinitWallet);    } catch (e) { @@ -461,7 +460,7 @@ try {   *   * Sets up all event handlers and other machinery.   */ -export async function wxMain() { +export async function wxMain(): Promise<void> {    // Explicitly unload the extension page as soon as an update is available,    // so the update gets installed as soon as possible.    chrome.runtime.onUpdateAvailable.addListener((details) => { @@ -505,8 +504,13 @@ export async function wxMain() {    chrome.tabs.onRemoved.addListener((tabId, changeInfo) => {      const tt = tabTimers[tabId] || []; +    const bgPage = chrome.extension.getBackgroundPage(); +    if (!bgPage) { +      console.error("background page unavailable"); +      return; +    }      for (const t of tt) { -      chrome.extension.getBackgroundPage()!.clearTimeout(t); +      bgPage.clearTimeout(t);      }    });    chrome.tabs.onUpdated.addListener((tabId, changeInfo) => { @@ -515,12 +519,7 @@ export async function wxMain() {      }      const timers: number[] = []; -    const addRun = (dt: number) => { -      const id = chrome.extension.getBackgroundPage()!.setTimeout(run, dt); -      timers.push(id); -    }; - -    const run = () => { +    const run = (): void => {        timers.shift();        chrome.tabs.get(tabId, (tab) => {          if (chrome.runtime.lastError) { @@ -538,10 +537,20 @@ export async function wxMain() {              document.dispatchEvent(new Event("taler-probe-result"));            }          `; -        injectScript(tab.id!, { code, runAt: "document_start" }, uri.href); +        injectScript(tab.id, { code, runAt: "document_start" }, uri.href);        });      }; +    const addRun = (dt: number): void => { +      const bgPage = chrome.extension.getBackgroundPage(); +      if (!bgPage) { +        console.error("no background page"); +        return; +      } +      const id = bgPage.setTimeout(run, dt); +      timers.push(id); +    }; +      addRun(0);      addRun(50);      addRun(300);  | 
