UNPKG

pawtils

Version:

This repository contains several utils to work with the cryptocurrency [Paw](https://paw.digital/) inside the browser.

1,728 lines (1,637 loc) 152 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var fetch = require('cross-fetch'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch); let crypto$2 = null; if (typeof window !== "undefined") { crypto$2 = window.crypto; } else { crypto$2 = require("crypto").webcrypto; } var crypto$3 = crypto$2; const ERROR_MSG_INPUT = 'Input must be an string, Buffer or Uint8Array'; // For convenience, let people hash a string, not just a Uint8Array function normalizeInput (input) { let ret; if (input instanceof Uint8Array) { ret = input; } else if (typeof input === 'string') { const encoder = new TextEncoder(); ret = encoder.encode(input); } else { throw new Error(ERROR_MSG_INPUT) } return ret } // Converts a Uint8Array to a hexadecimal string // For example, toHex([255, 0, 255]) returns "ff00ff" function toHex (bytes) { return Array.prototype.map .call(bytes, function (n) { return (n < 16 ? '0' : '') + n.toString(16) }) .join('') } // Converts any value in [0...2^32-1] to an 8-character hex string function uint32ToHex (val) { return (0x100000000 + val).toString(16).substring(1) } // For debugging: prints out hash state in the same format as the RFC // sample computation exactly, so that you can diff function debugPrint (label, arr, size) { let msg = '\n' + label + ' = '; for (let i = 0; i < arr.length; i += 2) { if (size === 32) { msg += uint32ToHex(arr[i]).toUpperCase(); msg += ' '; msg += uint32ToHex(arr[i + 1]).toUpperCase(); } else if (size === 64) { msg += uint32ToHex(arr[i + 1]).toUpperCase(); msg += uint32ToHex(arr[i]).toUpperCase(); } else throw new Error('Invalid size ' + size) if (i % 6 === 4) { msg += '\n' + new Array(label.length + 4).join(' '); } else if (i < arr.length - 2) { msg += ' '; } } console.log(msg); } // For performance testing: generates N bytes of input, hashes M times // Measures and prints MB/second hash performance each time function testSpeed (hashFn, N, M) { let startMs = new Date().getTime(); const input = new Uint8Array(N); for (let i = 0; i < N; i++) { input[i] = i % 256; } const genMs = new Date().getTime(); console.log('Generated random input in ' + (genMs - startMs) + 'ms'); startMs = genMs; for (let i = 0; i < M; i++) { const hashHex = hashFn(input); const hashMs = new Date().getTime(); const ms = hashMs - startMs; startMs = hashMs; console.log('Hashed in ' + ms + 'ms: ' + hashHex.substring(0, 20) + '...'); console.log( Math.round((N / (1 << 20) / (ms / 1000)) * 100) / 100 + ' MB PER SECOND' ); } } var util$2 = { normalizeInput: normalizeInput, toHex: toHex, debugPrint: debugPrint, testSpeed: testSpeed }; // Blake2B in pure Javascript // Adapted from the reference implementation in RFC7693 // Ported to Javascript by DC - https://github.com/dcposch const util$1 = util$2; // 64-bit unsigned addition // Sets v[a,a+1] += v[b,b+1] // v should be a Uint32Array function ADD64AA (v, a, b) { const o0 = v[a] + v[b]; let o1 = v[a + 1] + v[b + 1]; if (o0 >= 0x100000000) { o1++; } v[a] = o0; v[a + 1] = o1; } // 64-bit unsigned addition // Sets v[a,a+1] += b // b0 is the low 32 bits of b, b1 represents the high 32 bits function ADD64AC (v, a, b0, b1) { let o0 = v[a] + b0; if (b0 < 0) { o0 += 0x100000000; } let o1 = v[a + 1] + b1; if (o0 >= 0x100000000) { o1++; } v[a] = o0; v[a + 1] = o1; } // Little-endian byte access function B2B_GET32 (arr, i) { return arr[i] ^ (arr[i + 1] << 8) ^ (arr[i + 2] << 16) ^ (arr[i + 3] << 24) } // G Mixing function // The ROTRs are inlined for speed function B2B_G (a, b, c, d, ix, iy) { const x0 = m$2[ix]; const x1 = m$2[ix + 1]; const y0 = m$2[iy]; const y1 = m$2[iy + 1]; ADD64AA(v$2, a, b); // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s ADD64AC(v$2, a, x0, x1); // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits let xor0 = v$2[d] ^ v$2[a]; let xor1 = v$2[d + 1] ^ v$2[a + 1]; v$2[d] = xor1; v$2[d + 1] = xor0; ADD64AA(v$2, c, d); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits xor0 = v$2[b] ^ v$2[c]; xor1 = v$2[b + 1] ^ v$2[c + 1]; v$2[b] = (xor0 >>> 24) ^ (xor1 << 8); v$2[b + 1] = (xor1 >>> 24) ^ (xor0 << 8); ADD64AA(v$2, a, b); ADD64AC(v$2, a, y0, y1); // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits xor0 = v$2[d] ^ v$2[a]; xor1 = v$2[d + 1] ^ v$2[a + 1]; v$2[d] = (xor0 >>> 16) ^ (xor1 << 16); v$2[d + 1] = (xor1 >>> 16) ^ (xor0 << 16); ADD64AA(v$2, c, d); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits xor0 = v$2[b] ^ v$2[c]; xor1 = v$2[b + 1] ^ v$2[c + 1]; v$2[b] = (xor1 >>> 31) ^ (xor0 << 1); v$2[b + 1] = (xor0 >>> 31) ^ (xor1 << 1); } // Initialization Vector const BLAKE2B_IV32 = new Uint32Array([ 0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a, 0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19 ]); const SIGMA8 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ]; // These are offsets into a uint64 buffer. // Multiply them all by 2 to make them offsets into a uint32 buffer, // because this is Javascript and we don't have uint64s const SIGMA82 = new Uint8Array( SIGMA8.map(function (x) { return x * 2 }) ); // Compression function. 'last' flag indicates last block. // Note we're representing 16 uint64s as 32 uint32s const v$2 = new Uint32Array(32); const m$2 = new Uint32Array(32); function blake2bCompress (ctx, last) { let i = 0; // init work variables for (i = 0; i < 16; i++) { v$2[i] = ctx.h[i]; v$2[i + 16] = BLAKE2B_IV32[i]; } // low 64 bits of offset v$2[24] = v$2[24] ^ ctx.t; v$2[25] = v$2[25] ^ (ctx.t / 0x100000000); // high 64 bits not supported, offset may not be higher than 2**53-1 // last block flag set ? if (last) { v$2[28] = ~v$2[28]; v$2[29] = ~v$2[29]; } // get little-endian words for (i = 0; i < 32; i++) { m$2[i] = B2B_GET32(ctx.b, 4 * i); } // twelve rounds of mixing // uncomment the DebugPrint calls to log the computation // and match the RFC sample documentation // util.debugPrint(' m[16]', m, 64) for (i = 0; i < 12; i++) { // util.debugPrint(' (i=' + (i < 10 ? ' ' : '') + i + ') v[16]', v, 64) B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]); B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]); B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]); B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]); B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]); B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]); B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]); B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]); } // util.debugPrint(' (i=12) v[16]', v, 64) for (i = 0; i < 16; i++) { ctx.h[i] = ctx.h[i] ^ v$2[i] ^ v$2[i + 16]; } // util.debugPrint('h[8]', ctx.h, 64) } // reusable parameterBlock const parameterBlock = new Uint8Array([ 0, 0, 0, 0, // 0: outlen, keylen, fanout, depth 0, 0, 0, 0, // 4: leaf length, sequential mode 0, 0, 0, 0, // 8: node offset 0, 0, 0, 0, // 12: node offset 0, 0, 0, 0, // 16: node depth, inner length, rfu 0, 0, 0, 0, // 20: rfu 0, 0, 0, 0, // 24: rfu 0, 0, 0, 0, // 28: rfu 0, 0, 0, 0, // 32: salt 0, 0, 0, 0, // 36: salt 0, 0, 0, 0, // 40: salt 0, 0, 0, 0, // 44: salt 0, 0, 0, 0, // 48: personal 0, 0, 0, 0, // 52: personal 0, 0, 0, 0, // 56: personal 0, 0, 0, 0 // 60: personal ]); // Creates a BLAKE2b hashing context // Requires an output length between 1 and 64 bytes // Takes an optional Uint8Array key // Takes an optinal Uint8Array salt // Takes an optinal Uint8Array personal function blake2bInit (outlen, key, salt, personal) { if (outlen === 0 || outlen > 64) { throw new Error('Illegal output length, expected 0 < length <= 64') } if (key && key.length > 64) { throw new Error('Illegal key, expected Uint8Array with 0 < length <= 64') } if (salt && salt.length !== 16) { throw new Error('Illegal salt, expected Uint8Array with length is 16') } if (personal && personal.length !== 16) { throw new Error('Illegal personal, expected Uint8Array with length is 16') } // state, 'param block' const ctx = { b: new Uint8Array(128), h: new Uint32Array(16), t: 0, // input count c: 0, // pointer within buffer outlen: outlen // output length in bytes }; // initialize parameterBlock before usage parameterBlock.fill(0); parameterBlock[0] = outlen; if (key) parameterBlock[1] = key.length; parameterBlock[2] = 1; // fanout parameterBlock[3] = 1; // depth if (salt) parameterBlock.set(salt, 32); if (personal) parameterBlock.set(personal, 48); // initialize hash state for (let i = 0; i < 16; i++) { ctx.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameterBlock, i * 4); } // key the hash, if applicable if (key) { blake2bUpdate(ctx, key); // at the end ctx.c = 128; } return ctx } // Updates a BLAKE2b streaming hash // Requires hash context and Uint8Array (byte array) function blake2bUpdate (ctx, input) { for (let i = 0; i < input.length; i++) { if (ctx.c === 128) { // buffer full ? ctx.t += ctx.c; // add counters blake2bCompress(ctx, false); // compress (not last) ctx.c = 0; // counter to zero } ctx.b[ctx.c++] = input[i]; } } // Completes a BLAKE2b streaming hash // Returns a Uint8Array containing the message digest function blake2bFinal (ctx) { ctx.t += ctx.c; // mark last block offset while (ctx.c < 128) { // fill up with zeros ctx.b[ctx.c++] = 0; } blake2bCompress(ctx, true); // final block flag = 1 // little endian convert and store const out = new Uint8Array(ctx.outlen); for (let i = 0; i < ctx.outlen; i++) { out[i] = ctx.h[i >> 2] >> (8 * (i & 3)); } return out } // Computes the BLAKE2B hash of a string or byte array, and returns a Uint8Array // // Returns a n-byte Uint8Array // // Parameters: // - input - the input bytes, as a string, Buffer or Uint8Array // - key - optional key Uint8Array, up to 64 bytes // - outlen - optional output length in bytes, default 64 // - salt - optional salt bytes, string, Buffer or Uint8Array // - personal - optional personal bytes, string, Buffer or Uint8Array function blake2b (input, key, outlen, salt, personal) { // preprocess inputs outlen = outlen || 64; input = util$1.normalizeInput(input); if (salt) { salt = util$1.normalizeInput(salt); } if (personal) { personal = util$1.normalizeInput(personal); } // do the math const ctx = blake2bInit(outlen, key, salt, personal); blake2bUpdate(ctx, input); return blake2bFinal(ctx) } // Computes the BLAKE2B hash of a string or byte array // // Returns an n-byte hash in hex, all lowercase // // Parameters: // - input - the input bytes, as a string, Buffer, or Uint8Array // - key - optional key Uint8Array, up to 64 bytes // - outlen - optional output length in bytes, default 64 // - salt - optional salt bytes, string, Buffer or Uint8Array // - personal - optional personal bytes, string, Buffer or Uint8Array function blake2bHex (input, key, outlen, salt, personal) { const output = blake2b(input, key, outlen, salt, personal); return util$1.toHex(output) } var blake2b_1 = { blake2b: blake2b, blake2bHex: blake2bHex, blake2bInit: blake2bInit, blake2bUpdate: blake2bUpdate, blake2bFinal: blake2bFinal }; // BLAKE2s hash function in pure Javascript // Adapted from the reference implementation in RFC7693 // Ported to Javascript by DC - https://github.com/dcposch const util = util$2; // Little-endian byte access. // Expects a Uint8Array and an index // Returns the little-endian uint32 at v[i..i+3] function B2S_GET32 (v, i) { return v[i] ^ (v[i + 1] << 8) ^ (v[i + 2] << 16) ^ (v[i + 3] << 24) } // Mixing function G. function B2S_G (a, b, c, d, x, y) { v$1[a] = v$1[a] + v$1[b] + x; v$1[d] = ROTR32(v$1[d] ^ v$1[a], 16); v$1[c] = v$1[c] + v$1[d]; v$1[b] = ROTR32(v$1[b] ^ v$1[c], 12); v$1[a] = v$1[a] + v$1[b] + y; v$1[d] = ROTR32(v$1[d] ^ v$1[a], 8); v$1[c] = v$1[c] + v$1[d]; v$1[b] = ROTR32(v$1[b] ^ v$1[c], 7); } // 32-bit right rotation // x should be a uint32 // y must be between 1 and 31, inclusive function ROTR32 (x, y) { return (x >>> y) ^ (x << (32 - y)) } // Initialization Vector. const BLAKE2S_IV = new Uint32Array([ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]); const SIGMA = new Uint8Array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ]); // Compression function. "last" flag indicates last block const v$1 = new Uint32Array(16); const m$1 = new Uint32Array(16); function blake2sCompress (ctx, last) { let i = 0; for (i = 0; i < 8; i++) { // init work variables v$1[i] = ctx.h[i]; v$1[i + 8] = BLAKE2S_IV[i]; } v$1[12] ^= ctx.t; // low 32 bits of offset v$1[13] ^= ctx.t / 0x100000000; // high 32 bits if (last) { // last block flag set ? v$1[14] = ~v$1[14]; } for (i = 0; i < 16; i++) { // get little-endian words m$1[i] = B2S_GET32(ctx.b, 4 * i); } // ten rounds of mixing // uncomment the DebugPrint calls to log the computation // and match the RFC sample documentation // util.debugPrint(' m[16]', m, 32) for (i = 0; i < 10; i++) { // util.debugPrint(' (i=' + i + ') v[16]', v, 32) B2S_G(0, 4, 8, 12, m$1[SIGMA[i * 16 + 0]], m$1[SIGMA[i * 16 + 1]]); B2S_G(1, 5, 9, 13, m$1[SIGMA[i * 16 + 2]], m$1[SIGMA[i * 16 + 3]]); B2S_G(2, 6, 10, 14, m$1[SIGMA[i * 16 + 4]], m$1[SIGMA[i * 16 + 5]]); B2S_G(3, 7, 11, 15, m$1[SIGMA[i * 16 + 6]], m$1[SIGMA[i * 16 + 7]]); B2S_G(0, 5, 10, 15, m$1[SIGMA[i * 16 + 8]], m$1[SIGMA[i * 16 + 9]]); B2S_G(1, 6, 11, 12, m$1[SIGMA[i * 16 + 10]], m$1[SIGMA[i * 16 + 11]]); B2S_G(2, 7, 8, 13, m$1[SIGMA[i * 16 + 12]], m$1[SIGMA[i * 16 + 13]]); B2S_G(3, 4, 9, 14, m$1[SIGMA[i * 16 + 14]], m$1[SIGMA[i * 16 + 15]]); } // util.debugPrint(' (i=10) v[16]', v, 32) for (i = 0; i < 8; i++) { ctx.h[i] ^= v$1[i] ^ v$1[i + 8]; } // util.debugPrint('h[8]', ctx.h, 32) } // Creates a BLAKE2s hashing context // Requires an output length between 1 and 32 bytes // Takes an optional Uint8Array key function blake2sInit (outlen, key) { if (!(outlen > 0 && outlen <= 32)) { throw new Error('Incorrect output length, should be in [1, 32]') } const keylen = key ? key.length : 0; if (key && !(keylen > 0 && keylen <= 32)) { throw new Error('Incorrect key length, should be in [1, 32]') } const ctx = { h: new Uint32Array(BLAKE2S_IV), // hash state b: new Uint8Array(64), // input block c: 0, // pointer within block t: 0, // input count outlen: outlen // output length in bytes }; ctx.h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen; if (keylen > 0) { blake2sUpdate(ctx, key); ctx.c = 64; // at the end } return ctx } // Updates a BLAKE2s streaming hash // Requires hash context and Uint8Array (byte array) function blake2sUpdate (ctx, input) { for (let i = 0; i < input.length; i++) { if (ctx.c === 64) { // buffer full ? ctx.t += ctx.c; // add counters blake2sCompress(ctx, false); // compress (not last) ctx.c = 0; // counter to zero } ctx.b[ctx.c++] = input[i]; } } // Completes a BLAKE2s streaming hash // Returns a Uint8Array containing the message digest function blake2sFinal (ctx) { ctx.t += ctx.c; // mark last block offset while (ctx.c < 64) { // fill up with zeros ctx.b[ctx.c++] = 0; } blake2sCompress(ctx, true); // final block flag = 1 // little endian convert and store const out = new Uint8Array(ctx.outlen); for (let i = 0; i < ctx.outlen; i++) { out[i] = (ctx.h[i >> 2] >> (8 * (i & 3))) & 0xff; } return out } // Computes the BLAKE2S hash of a string or byte array, and returns a Uint8Array // // Returns a n-byte Uint8Array // // Parameters: // - input - the input bytes, as a string, Buffer, or Uint8Array // - key - optional key Uint8Array, up to 32 bytes // - outlen - optional output length in bytes, default 64 function blake2s (input, key, outlen) { // preprocess inputs outlen = outlen || 32; input = util.normalizeInput(input); // do the math const ctx = blake2sInit(outlen, key); blake2sUpdate(ctx, input); return blake2sFinal(ctx) } // Computes the BLAKE2S hash of a string or byte array // // Returns an n-byte hash in hex, all lowercase // // Parameters: // - input - the input bytes, as a string, Buffer, or Uint8Array // - key - optional key Uint8Array, up to 32 bytes // - outlen - optional output length in bytes, default 64 function blake2sHex (input, key, outlen) { const output = blake2s(input, key, outlen); return util.toHex(output) } var blake2s_1 = { blake2s: blake2s, blake2sHex: blake2sHex, blake2sInit: blake2sInit, blake2sUpdate: blake2sUpdate, blake2sFinal: blake2sFinal }; const b2b = blake2b_1; const b2s = blake2s_1; var blakejs = { blake2b: b2b.blake2b, blake2bHex: b2b.blake2bHex, blake2bInit: b2b.blake2bInit, blake2bUpdate: b2b.blake2bUpdate, blake2bFinal: b2b.blake2bFinal, blake2s: b2s.blake2s, blake2sHex: b2s.blake2sHex, blake2sInit: b2s.blake2sInit, blake2sUpdate: b2s.blake2sUpdate, blake2sFinal: b2s.blake2sFinal }; // @ts-nocheck function hexToBytes$1(hex) { const result = new Uint8Array(hex.length / 2); for (let ii = 0; ii < result.length; ++ii) { result[ii] = parseInt(hex.substring((ii * 2) + 0, (ii * 2) + 2), 16); } return result; } const gf = function (init) { let i; const r = new Float64Array(16); if (init) { for (i = 0; i < init.length; i++) { r[i] = init[i]; } } return r; }; const _9 = new Uint8Array(32); _9[0] = 9; const gf0 = gf(); const gf1 = gf([1]); gf([0xdb41, 1]); gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]); const D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]); const X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]); const Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]); gf([ 0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83 ]); function set25519(r, a) { let i; for (i = 0; i < 16; i++) { r[i] = a[i] | 0; } } function car25519(o) { let c; let i; for (i = 0; i < 16; i++) { o[i] += 65536; c = Math.floor(o[i] / 65536); o[(i + 1) * (i < 15 ? 1 : 0)] += c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0); o[i] -= (c * 65536); } } function sel25519(p, q, b) { let t; const c = ~(b - 1); for (let i = 0; i < 16; i++) { t = c & (p[i] ^ q[i]); p[i] ^= t; q[i] ^= t; } } function pack25519(o, n) { let i; let j; let b; const m = gf(); const t = gf(); for (i = 0; i < 16; i++) { t[i] = n[i]; } car25519(t); car25519(t); car25519(t); for (j = 0; j < 2; j++) { m[0] = t[0] - 0xffed; for (i = 1; i < 15; i++) { m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); m[i - 1] &= 0xffff; } m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); b = (m[15] >> 16) & 1; m[14] &= 0xffff; sel25519(t, m, 1 - b); } for (i = 0; i < 16; i++) { o[2 * i] = t[i] & 0xff; o[2 * i + 1] = t[i] >> 8; } } function par25519(a) { const d = new Uint8Array(32); pack25519(d, a); return d[0] & 1; } function A$1(o, a, b) { let i; for (i = 0; i < 16; i++) { o[i] = (a[i] + b[i]) | 0; } } function Z(o, a, b) { let i; for (i = 0; i < 16; i++) { o[i] = (a[i] - b[i]) | 0; } } function M$1(o, a, b) { let i; let j; const t = new Float64Array(31); for (i = 0; i < 31; i++) { t[i] = 0; } for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { t[i + j] += a[i] * b[j]; } } for (i = 0; i < 15; i++) { t[i] += 38 * t[i + 16]; } for (i = 0; i < 16; i++) { o[i] = t[i]; } car25519(o); car25519(o); } function S(o, a) { M$1(o, a, a); } function inv25519(o, i) { const c = gf(); let a; for (a = 0; a < 16; a++) { c[a] = i[a]; } for (a = 253; a >= 0; a--) { S(c, c); if (a !== 2 && a !== 4) { M$1(c, c, i); } } for (a = 0; a < 16; a++) { o[a] = c[a]; } } function add(p, q) { const a = gf(); const b = gf(); const c = gf(); const d = gf(); const e = gf(); const f = gf(); const g = gf(); const h = gf(); const t = gf(); Z(a, p[1], p[0]); Z(t, q[1], q[0]); M$1(a, a, t); A$1(b, p[0], p[1]); A$1(t, q[0], q[1]); M$1(b, b, t); M$1(c, p[3], q[3]); M$1(c, c, D2); M$1(d, p[2], q[2]); A$1(d, d, d); Z(e, b, a); Z(f, d, c); A$1(g, d, c); A$1(h, b, a); M$1(p[0], e, f); M$1(p[1], h, g); M$1(p[2], g, f); M$1(p[3], e, h); } function cswap(p, q, b) { let i; for (i = 0; i < 4; i++) { sel25519(p[i], q[i], b); } } function pack(r, p) { const tx = gf(); const ty = gf(); const zi = gf(); inv25519(zi, p[2]); M$1(tx, p[0], zi); M$1(ty, p[1], zi); pack25519(r, ty); r[31] ^= par25519(tx) << 7; } function scalarmult(p, q, s) { let b; let i; set25519(p[0], gf0); set25519(p[1], gf1); set25519(p[2], gf1); set25519(p[3], gf0); for (i = 255; i >= 0; --i) { b = (s[(i / 8) | 0] >> (i & 7)) & 1; cswap(p, q, b); add(q, p); add(p, p); cswap(p, q, b); } } function scalarbase(p, s) { const q = [gf(), gf(), gf(), gf()]; set25519(q[0], X); set25519(q[1], Y); set25519(q[2], gf1); M$1(q[3], X, Y); scalarmult(p, q, s); } const uint5ToUint4 = (uint5) => { const length = uint5.length / 4 * 5; const uint4 = new Uint8Array(length); for (let i = 1; i <= length; i++) { const n = i - 1; const m = i % 5; const z = n - ((i - m) / 5); const right = uint5[z - 1] << (5 - m); const left = uint5[z] >> m; uint4[n] = (left + right) % 16; } return uint4; }; const arrayCrop = (array) => { const length = array.length - 1; const croppedArray = new Uint8Array(length); for (let i = 0; i < length; i++) { croppedArray[i] = array[i + 1]; } return croppedArray; }; const uint4ToHex = (uint4) => { let hex = ''; for (let i = 0; i < uint4.length; i++) { hex += uint4[i].toString(16).toUpperCase(); } return hex; }; const uint8ToUint4 = (uintValue) => { const uint4 = new Uint8Array(uintValue.length * 2); for (let i = 0; i < uintValue.length; i++) { uint4[i * 2] = uintValue[i] / 16 | 0; uint4[i * 2 + 1] = uintValue[i] % 16; } return uint4; }; const equalArrays = (array1, array2) => { for (let i = 0; i < array1.length; i++) { if (array1[i] != array2[i]) return false; } return true; }; const uint4ToUint8 = (uintValue) => { const length = uintValue.length / 2; const uint8 = new Uint8Array(length); for (let i = 0; i < length; i++) { uint8[i] = (uintValue[i * 2] * 16) + uintValue[i * 2 + 1]; } return uint8; }; const stringToUint5 = (string) => { const letterList = '13456789abcdefghijkmnopqrstuwxyz'.split(''); const length = string.length; const stringArray = string.split(''); const uint5 = new Uint8Array(length); for (let i = 0; i < length; i++) { uint5[i] = letterList.indexOf(stringArray[i]); } return uint5; }; const hexToUint4 = (hexValue) => { const uint4 = new Uint8Array(hexValue.length); for (let i = 0; i < hexValue.length; i++) { uint4[i] = parseInt(hexValue.substr(i, 1), 16); } return uint4; }; const uint4ToUint5 = (uintValue) => { const length = uintValue.length / 5 * 4; const uint5 = new Uint8Array(length); for (let i = 1; i <= length; i++) { const n = i - 1; const m = i % 4; const z = n + ((i - m) / 4); const right = uintValue[z] << m; let left; if (((length - i) % 4) == 0) { left = uintValue[z - 1] << 4; } else { left = uintValue[z + 1] >> (4 - m); } uint5[n] = (left + right) % 32; } return uint5; }; const uint5ToString = (uint5) => { const letterList = '13456789abcdefghijkmnopqrstuwxyz'.split(''); let string = ''; for (let i = 0; i < uint5.length; i++) { string += letterList[uint5[i]]; } return string; }; const L$1 = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); function modL(r, x) { let carry; let i; let j; let k; for (i = 63; i >= 32; --i) { carry = 0; for (j = i - 32, k = i - 12; j < k; ++j) { x[j] += carry - 16 * x[i] * L$1[j - (i - 32)]; carry = (x[j] + 128) >> 8; x[j] -= carry * 256; } x[j] += carry; x[i] = 0; } carry = 0; for (j = 0; j < 32; j++) { x[j] += carry - (x[31] >> 4) * L$1[j]; carry = x[j] >> 8; x[j] &= 255; } for (j = 0; j < 32; j++) { x[j] -= carry * L$1[j]; } for (i = 0; i < 32; i++) { x[i + 1] += x[i] >> 8; r[i] = x[i] & 255; } } function reduce(r) { const x = new Float64Array(64); let i; for (i = 0; i < 64; i++) { x[i] = r[i]; } for (i = 0; i < 64; i++) { r[i] = 0; } modL(r, x); } // Note: difference from C - smlen returned, not passed as argument. function crypto_sign(sm, m, n, sk) { let d = new Uint8Array(64); let h = new Uint8Array(64); let r = new Uint8Array(64); let i; let j; const x = new Float64Array(64); const p = [gf(), gf(), gf(), gf()]; const pk = derivePublicKeyFromPrivateKey(sk); let context = blakejs.blake2bInit(64, null); blakejs.blake2bUpdate(context, sk); d = blakejs.blake2bFinal(context); d[0] &= 248; d[31] &= 127; d[31] |= 64; const smlen = n + 64; for (i = 0; i < n; i++) { sm[64 + i] = m[i]; } for (i = 0; i < 32; i++) { sm[32 + i] = d[32 + i]; } context = blakejs.blake2bInit(64, null); blakejs.blake2bUpdate(context, sm.subarray(32)); r = blakejs.blake2bFinal(context); reduce(r); scalarbase(p, r); pack(sm, p); for (i = 32; i < 64; i++) { sm[i] = pk[i - 32]; } context = blakejs.blake2bInit(64, null); blakejs.blake2bUpdate(context, sm); h = blakejs.blake2bFinal(context); reduce(h); for (i = 0; i < 64; i++) { x[i] = 0; } for (i = 0; i < 32; i++) { x[i] = r[i]; } for (i = 0; i < 32; i++) { for (j = 0; j < 32; j++) { x[i + j] += h[i] * d[j]; } } modL(sm.subarray(32), x); return smlen; } function deriveAddressFromPublicKey(publicKey) { const keyBytes = uint4ToUint8(hexToUint4(publicKey)); // For some reason here we go from u, to hex, to 4, to 8?? const checksum = uint5ToString(uint4ToUint5(uint8ToUint4(blakejs.blake2b(keyBytes, null, 5).reverse()))); const address = uint5ToString(uint4ToUint5(hexToUint4(`0${publicKey}`))); return `paw_${address}${checksum}`; } function derivePublicKeyFromPrivateKey(privateKey) { let d = new Uint8Array(64); const p = [gf(), gf(), gf(), gf()]; const pk = new Uint8Array(32); const context = blakejs.blake2bInit(64); blakejs.blake2bUpdate(context, privateKey); d = blakejs.blake2bFinal(context); d[0] &= 248; d[31] &= 127; d[31] |= 64; scalarbase(p, d); pack(pk, p); return pk; } function derivePublicKeyFromAddress(address) { let addressCrop = address.substring(4, 64); const keyUint4 = arrayCrop(uint5ToUint4(stringToUint5(addressCrop.substring(0, 52)))); const hashUint4 = uint5ToUint4(stringToUint5(addressCrop.substring(52, 60))); const keyArray = uint4ToUint8(keyUint4); const blakeHash = blakejs.blake2b(keyArray, null, 5).reverse(); const left = hashUint4; const right = uint8ToUint4(blakeHash); if (!equalArrays(left, right)) { const leftStr = uint5ToString(uint4ToUint5(left)); const rightStr = uint5ToString(uint4ToUint5(right)); throw new Error(`Incorrect checksum ${leftStr} != ${rightStr}`); } return hexToBytes$1(uint4ToHex(keyUint4)); } function signHash(privateKey, hash) { const signedMsg = new Uint8Array(64 + hash.length); crypto_sign(signedMsg, hash, hash.length, privateKey); const sig = new Uint8Array(64); for (let i = 0; i < sig.length; i++) { sig[i] = signedMsg[i]; } return sig; } const WORK_DIFFICULTY = 0xfffffff8; const MAJOR_DIVISOR = 1000000000000000000000000000n; const MINOR_DIVISOR = 1000000000000000000000000000n; const SEED_ALPHABET_REGEX = new RegExp(`^[0123456789abcdefABCDEF]{64}$`); /** * Decodes the provided base64 encoded wasm stub * @param stub - The base64 wasm stub */ function decodeWasmModule$1(stub) { const str = atob(stub); const buffer = new Uint8Array(str.length); for (let ii = 0; ii < str.length; ++ii) buffer[ii] = str.charCodeAt(ii); return buffer; } /** * Clamps the provided number between the given min/max range * @param num - The number to clamp * @param min - The minimum clamp bound * @param max - The maximum clamp bound */ function clamp(num, min, max) { return Math.max(min, Math.min(num, max)); } /** * Converts the provided hex into the equivalent bytes * @param hex - The hex to convert */ function hexToBytes(hex) { const result = new Uint8Array(hex.length / 2); for (let ii = 0; ii < result.length; ++ii) { result[ii] = parseInt(hex.substring((ii * 2) + 0, (ii * 2) + 2), 16); } return result; } /** * Converts the provided bytes into their hexadecimal equivalent * @param bytes - The bytes to convert */ function bytesToHex$1(bytes) { return Array.prototype.map.call(bytes, (x) => ("00" + x.toString(16)).slice(-2)).join("").toUpperCase(); } /** * Converts the provided bits into a number * @param bits - The bits to convert * @param bitStride - An optional bit stride */ function bitsToNumber(bits, bitStride = 8) { let number = 0; for (let bb = bitStride - 1; bb >= 0; --bb) { number |= (bits[bb] << bb); } return number; } /** * Converts the provided number into it's bit equivalent * @param number - The number to convert * @param bitStride - An optional bit stride */ function numberToBits(number, bitStride = 8) { const bits = new Uint8Array(bitStride); for (let bb = bitStride - 1; bb >= 0; --bb) { bits[bitStride - 1 - bb] = number & (1 << bb) ? 1 : 0; } return bits; } /** * Converts the provided bytes into their bit equivalent * @param bytes - The bytes to convert */ function bytesToBits(bytes) { const bits = new Uint8Array(bytes.length * 8); for (let ii = 0; ii < bytes.length; ++ii) { const b = numberToBits(bytes[ii], 8); for (let bb = 0; bb < 8; ++bb) { bits[(ii * 8) + bb] = b[bb]; } } return bits; } /** * Converts the provided 1-d bits into N-d bits * @param bitsn - The 1-d bits to convert * @param bitStride - The bit stride to use */ function bitsToBitsN(bits, bitStride) { const output = new Uint8Array(Math.ceil(bits.length / bitStride)); for (let ii = 0; ii < output.length; ++ii) { output[ii] = bitsToNumber(bits.subarray((ii * bitStride) + 0, (ii * bitStride) + bitStride), bitStride); } return output; } /** * Converts the provided N-d bits into 1-d bits * @param bitsn - The N-d bits to convert * @param bitStride - The bit stride to use */ function bitsNToBits(bitsn, bitStride) { const output = new Uint8Array(Math.floor(bitsn.length * bitStride)); for (let ii = 0; ii < bitsn.length; ++ii) { const bits = numberToBits(bitsn[ii], bitStride); for (let bb = 0; bb < bitStride; ++bb) { output[(ii * bitStride) + bb] = bits[bitStride - 1 - bb]; } } return output; } /** * Converts the provided decimal value into the hexadecimal equivalent * @param decimal - The decimal value to convert * @param bytes - The byte stride of the provided value */ function decimalToHex(decimal, bytes) { const dec = decimal.toString().split(""); const sum = []; let hex = ""; const hexArray = []; while (dec.length) { let s = 1 * Number(dec.shift()); for (let ii = 0; s || ii < sum.length; ++ii) { s += (sum[ii] || 0) * 10; sum[ii] = s % 16; s = (s - sum[ii]) / 16; } } while (sum.length) { hexArray.push(sum.pop().toString(16)); } hex = hexArray.join(""); if (hex.length % 2 != 0) hex = "0" + hex; if (bytes > hex.length / 2) { const diff = bytes - (hex.length / 2); for (let j = 0; j < diff; j++) { hex = "00" + hex; } } return hex; } /** * Indicates if the provided seed is valid * @param seed - The seed to check */ function isSeedValid(seed) { return SEED_ALPHABET_REGEX.test(bytesToHex$1(seed)); } /** * Indicates if the provided hash and work bytes are valid * @param hash - The hash to validate * @param work - The work to validate * @param workMin - The minimum value of the work */ function isWorkValid(hash, work, workMin) { const context = blakejs.blake2bInit(8); blakejs.blake2bUpdate(context, work); blakejs.blake2bUpdate(context, hash); const output = blakejs.blake2bFinal(context).reverse(); const outputHex = bytesToHex$1(output); const outputBigInt = BigInt("0x" + outputHex); return outputBigInt > workMin; } /** * Converts the provided amount into raw amount * @param amount - The amount to convert */ function getRawFromAmount(amount) { const decimalPlace = amount.indexOf("."); let divisor = BigInt("1"); if (decimalPlace !== -1) { amount = amount.replace(".", ""); const decimalsAfter = amount.length - decimalPlace; divisor = BigInt("100") ** BigInt(decimalsAfter); } const amountBi = BigInt(amount); const amountRaw = (amountBi * MAJOR_DIVISOR) / divisor; return amountRaw; } /** * Converts the provided raw amount into amount * @param amountRaw - The raw amount to convert */ function getAmountFromRaw(amountRaw) { const major = amountRaw / MAJOR_DIVISOR; const majorRawRemainder = amountRaw - (major * MAJOR_DIVISOR); const minor = majorRawRemainder / MINOR_DIVISOR; const banano = major.toString(); const banoshi = minor.toString(); const amount = banano + "." + banoshi.padStart(2, "0"); return amount; } /** * Returns the private key of the provided seed * @param seed - The seed to derive from * @param seedIx - The seed index */ function getPrivateKey(seed, seedIx = 0) { if (!isSeedValid(seed)) throw new Error(`Invalid seed '${seed}'`); const accountBytes = hexToBytes(decimalToHex(seedIx, 4)); const context = blakejs.blake2bInit(32); blakejs.blake2bUpdate(context, seed); blakejs.blake2bUpdate(context, accountBytes); return blakejs.blake2bFinal(context); } /** * Returns the public key of the provided input * @param input - The private key or address to derive from */ function getPublicKey(input) { // Get public key from address string if (typeof input === "string") { return derivePublicKeyFromAddress(input); } // Get public key from private key array return derivePublicKeyFromPrivateKey(input); } /** * Returns the relative address of the public key * @param publicKey - The public key to derive the address from */ function getAccountAddress(publicKey) { return deriveAddressFromPublicKey(bytesToHex$1(publicKey)); } /** * Encrypts the provided hash with the given password * @param hash - The hash to encrypt * @param password - The password to encrypt the hash with * @param iv - An optional initialization vector to encrypt with */ async function encryptHash(hash, password, iv = null) { const passwordBytes = new TextEncoder().encode(password); const passwordKey = await crypto$3.subtle.importKey("raw", passwordBytes, { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"]); const key = await crypto$3.subtle.deriveKey({ name: "PBKDF2", iterations: 100000, salt: new Uint8Array(16), hash: "SHA-256" }, passwordKey, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]); const encrypted = await crypto$3.subtle.encrypt({ name: "AES-GCM", iv: iv || new Uint8Array(12) }, key, hash); return new Uint8Array(encrypted); } /** * Decrypts the provided encrypted hash with the given password * @param hash - The hash to decrypt * @param password - The password to decrypt the hash with * @param iv - An optional initialization vector to decrypt with */ async function decryptHash(hash, password, iv = null) { const passwordBytes = new TextEncoder().encode(password); const passwordKey = await crypto$3.subtle.importKey("raw", passwordBytes, { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"]); const key = await crypto$3.subtle.deriveKey({ name: "PBKDF2", iterations: 100000, salt: new Uint8Array(16), hash: "SHA-256" }, passwordKey, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]); try { const decrypted = await crypto$3.subtle.decrypt({ name: "AES-GCM", iv: iv || new Uint8Array(12) }, key, hash); return new Uint8Array(decrypted); } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseAccountBalanceResponse(json) { try { const balance = Object.values(json.balances)[0]; const output = { balance: BigInt(balance.balance), pending: BigInt(balance.pending), }; return output; } catch (e) { } return null; } /** * Represents an account history item action */ var ACCOUNT_HISTORY_ITEM_ACTION; (function (ACCOUNT_HISTORY_ITEM_ACTION) { /** * History item send action */ ACCOUNT_HISTORY_ITEM_ACTION[ACCOUNT_HISTORY_ITEM_ACTION["SEND"] = 0] = "SEND"; /** * History item receive action */ ACCOUNT_HISTORY_ITEM_ACTION[ACCOUNT_HISTORY_ITEM_ACTION["RECEIVE"] = 1] = "RECEIVE"; })(ACCOUNT_HISTORY_ITEM_ACTION || (ACCOUNT_HISTORY_ITEM_ACTION = {})); /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseAccountHistoryResponse(json) { try { if (Array.isArray(json.history)) { const output = { history: [] }; for (const history of json.history) { output.history.push({ hash: hexToBytes(history.hash), amount: BigInt(history.amount), account: derivePublicKeyFromAddress(history.account), action: history.type === "send" ? ACCOUNT_HISTORY_ITEM_ACTION.SEND : ACCOUNT_HISTORY_ITEM_ACTION.RECEIVE, }); } return output; } } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseAccountInfoResponse(json) { try { const output = { blockCount: parseInt(json.block_count), frontier: hexToBytes(json.frontier), representativeBlock: hexToBytes(json.representative_block), modificationTimestamp: parseInt(json.modified_timestamp), }; return output; } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseAccountPendingResponse(json) { try { const output = { blocks: [] }; const blocks = Object.values(json.blocks)[0]; for (const [key, value] of Object.entries(blocks)) { const { amount, source } = value; const item = { amount: BigInt(amount), hash: hexToBytes(key), source: derivePublicKeyFromAddress(source) }; output.blocks.push(item); } return output; } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseAccountRepresentativeResponse(json) { try { const output = { account: derivePublicKeyFromAddress(json.representative) }; return output; } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseBlockProcessResponse(json) { try { const output = { hash: hexToBytes(json.hash) }; return output; } catch (e) { } return null; } /** * Parses the provided json into an abstract representation * @param json - The json to parse */ function parseWorkGenerateResponse(json) { try { const output = { work: hexToBytes(json.work), }; return output; } catch (e) { } return null; } /** * Decodes the provided base64 encoded wasm stub * @param stub - The base64 wasm stub */ function decodeWasmModule(stub) { const str = atob(stub); const buffer = new Uint8Array(str.length); for (let ii = 0; ii < str.length; ++ii) buffer[ii] = str.charCodeAt(ii); return buffer; } const IS_BROWSER = typeof window !== "undefined"; class CrossWorker { constructor(code) { this._instance = null; // Browser if (IS_BROWSER) { // Create worker blob const workerBlob = new Blob([code], { type: "text/javascript" }); const workerBlobURL = window.URL.createObjectURL(workerBlob); this._instance = new Worker(workerBlobURL); this._instance.onmessage = (e) => { this.onmessage(e); }; } // Node else { const { Worker } = require("worker_threads"); const worker = new Worker(code, { eval: true }); worker.on("message", (e) => { this.onmessage({ data: e }); }); this._instance = worker; } } postMessage(e) { if (IS_BROWSER) this._instance.postMessage(e); else { this._instance.postMessage(e); } } } var powC = `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