How to use crypto method in Best

Best JavaScript code snippet using best

nacl.js

Source:nacl.js Github

copy

Full Screen

1(function(nacl) {2'use strict';3// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.4// Public domain.5//6// Implementation derived from TweetNaCl version 20140427.7// See for details: http://tweetnacl.cr.yp.to/8var u64 = function(h, l) { this.hi = h|0 >>> 0; this.lo = l|0 >>> 0; };9var gf = function(init) {10 var i, r = new Float64Array(16);11 if (init) for (i = 0; i < init.length; i++) r[i] = init[i];12 return r;13};14// Pluggable, initialized in high-level API below.15var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };16var _0 = new Uint8Array(16);17var _9 = new Uint8Array(32); _9[0] = 9;18var gf0 = gf(),19 gf1 = gf([1]),20 _121665 = gf([0xdb41, 1]),21 D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),22 D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),23 X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),24 Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),25 I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);26function L32(x, c) { return (x << c) | (x >>> (32 - c)); }27function ld32(x, i) {28 var u = x[i+3] & 0xff;29 u = (u<<8)|(x[i+2] & 0xff);30 u = (u<<8)|(x[i+1] & 0xff);31 return (u<<8)|(x[i+0] & 0xff);32}33function dl64(x, i) {34 var h = (x[i] << 24) | (x[i+1] << 16) | (x[i+2] << 8) | x[i+3];35 var l = (x[i+4] << 24) | (x[i+5] << 16) | (x[i+6] << 8) | x[i+7];36 return new u64(h, l);37}38function st32(x, j, u) {39 var i;40 for (i = 0; i < 4; i++) { x[j+i] = u & 255; u >>>= 8; }41}42function ts64(x, i, u) {43 x[i] = (u.hi >> 24) & 0xff;44 x[i+1] = (u.hi >> 16) & 0xff;45 x[i+2] = (u.hi >> 8) & 0xff;46 x[i+3] = u.hi & 0xff;47 x[i+4] = (u.lo >> 24) & 0xff;48 x[i+5] = (u.lo >> 16) & 0xff;49 x[i+6] = (u.lo >> 8) & 0xff;50 x[i+7] = u.lo & 0xff;51}52function vn(x, xi, y, yi, n) {53 var i,d = 0;54 for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];55 return (1 & ((d - 1) >>> 8)) - 1;56}57function crypto_verify_16(x, xi, y, yi) {58 return vn(x,xi,y,yi,16);59}60function crypto_verify_32(x, xi, y, yi) {61 return vn(x,xi,y,yi,32);62}63function core(out,inp,k,c,h) {64 var w = new Uint32Array(16), x = new Uint32Array(16),65 y = new Uint32Array(16), t = new Uint32Array(4);66 var i, j, m;67 for (i = 0; i < 4; i++) {68 x[5*i] = ld32(c, 4*i);69 x[1+i] = ld32(k, 4*i);70 x[6+i] = ld32(inp, 4*i);71 x[11+i] = ld32(k, 16+4*i);72 }73 for (i = 0; i < 16; i++) y[i] = x[i];74 for (i = 0; i < 20; i++) {75 for (j = 0; j < 4; j++) {76 for (m = 0; m < 4; m++) t[m] = x[(5*j+4*m)%16];77 t[1] ^= L32((t[0]+t[3])|0, 7);78 t[2] ^= L32((t[1]+t[0])|0, 9);79 t[3] ^= L32((t[2]+t[1])|0,13);80 t[0] ^= L32((t[3]+t[2])|0,18);81 for (m = 0; m < 4; m++) w[4*j+(j+m)%4] = t[m];82 }83 for (m = 0; m < 16; m++) x[m] = w[m];84 }85 if (h) {86 for (i = 0; i < 16; i++) x[i] = (x[i] + y[i]) | 0;87 for (i = 0; i < 4; i++) {88 x[5*i] = (x[5*i] - ld32(c, 4*i)) | 0;89 x[6+i] = (x[6+i] - ld32(inp, 4*i)) | 0;90 }91 for (i = 0; i < 4; i++) {92 st32(out,4*i,x[5*i]);93 st32(out,16+4*i,x[6+i]);94 }95 } else {96 for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0);97 }98}99function crypto_core_salsa20(out,inp,k,c) {100 core(out,inp,k,c,false);101 return 0;102}103function crypto_core_hsalsa20(out,inp,k,c) {104 core(out,inp,k,c,true);105 return 0;106}107var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);108 // "expand 32-byte k"109function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {110 var z = new Uint8Array(16), x = new Uint8Array(64);111 var u, i;112 if (!b) return 0;113 for (i = 0; i < 16; i++) z[i] = 0;114 for (i = 0; i < 8; i++) z[i] = n[i];115 while (b >= 64) {116 crypto_core_salsa20(x,z,k,sigma);117 for (i = 0; i < 64; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];118 u = 1;119 for (i = 8; i < 16; i++) {120 u = u + (z[i] & 0xff) | 0;121 z[i] = u & 0xff;122 u >>>= 8;123 }124 b -= 64;125 cpos += 64;126 if (m) mpos += 64;127 }128 if (b > 0) {129 crypto_core_salsa20(x,z,k,sigma);130 for (i = 0; i < b; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];131 }132 return 0;133}134function crypto_stream_salsa20(c,cpos,d,n,k) {135 return crypto_stream_salsa20_xor(c,cpos,null,0,d,n,k);136}137function crypto_stream(c,cpos,d,n,k) {138 var s = new Uint8Array(32);139 crypto_core_hsalsa20(s,n,k,sigma);140 return crypto_stream_salsa20(c,cpos,d,n.subarray(16),s);141}142function crypto_stream_xor(c,cpos,m,mpos,d,n,k) {143 var s = new Uint8Array(32);144 crypto_core_hsalsa20(s,n,k,sigma);145 return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,n.subarray(16),s);146}147function add1305(h, c) {148 var j, u = 0;149 for (j = 0; j < 17; j++) {150 u = (u + ((h[j] + c[j]) | 0)) | 0;151 h[j] = u & 255;152 u >>>= 8;153 }154}155var minusp = new Uint32Array([156 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252157]);158function crypto_onetimeauth(out, outpos, m, mpos, n, k) {159 var s, i, j, u;160 var x = new Uint32Array(17), r = new Uint32Array(17),161 h = new Uint32Array(17), c = new Uint32Array(17),162 g = new Uint32Array(17);163 for (j = 0; j < 17; j++) r[j]=h[j]=0;164 for (j = 0; j < 16; j++) r[j]=k[j];165 r[3]&=15;166 r[4]&=252;167 r[7]&=15;168 r[8]&=252;169 r[11]&=15;170 r[12]&=252;171 r[15]&=15;172 while (n > 0) {173 for (j = 0; j < 17; j++) c[j] = 0;174 for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[mpos+j];175 c[j] = 1;176 mpos += j; n -= j;177 add1305(h,c);178 for (i = 0; i < 17; i++) {179 x[i] = 0;180 for (j = 0; j < 17; j++) x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j])|0))) | 0) | 0;181 }182 for (i = 0; i < 17; i++) h[i] = x[i];183 u = 0;184 for (j = 0; j < 16; j++) {185 u = (u + h[j]) | 0;186 h[j] = u & 255;187 u >>>= 8;188 }189 u = (u + h[16]) | 0; h[16] = u & 3;190 u = (5 * (u >>> 2)) | 0;191 for (j = 0; j < 16; j++) {192 u = (u + h[j]) | 0;193 h[j] = u & 255;194 u >>>= 8;195 }196 u = (u + h[16]) | 0; h[16] = u;197 }198 for (j = 0; j < 17; j++) g[j] = h[j];199 add1305(h,minusp);200 s = (-(h[16] >>> 7) | 0);201 for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j]);202 for (j = 0; j < 16; j++) c[j] = k[j + 16];203 c[16] = 0;204 add1305(h,c);205 for (j = 0; j < 16; j++) out[outpos+j] = h[j];206 return 0;207}208function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {209 var x = new Uint8Array(16);210 crypto_onetimeauth(x,0,m,mpos,n,k);211 return crypto_verify_16(h,hpos,x,0);212}213function crypto_secretbox(c,m,d,n,k) {214 var i;215 if (d < 32) return -1;216 crypto_stream_xor(c,0,m,0,d,n,k);217 crypto_onetimeauth(c, 16, c, 32, d - 32, c);218 for (i = 0; i < 16; i++) c[i] = 0;219 return 0;220}221function crypto_secretbox_open(m,c,d,n,k) {222 var i;223 var x = new Uint8Array(32);224 if (d < 32) return -1;225 crypto_stream(x,0,32,n,k);226 if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1;227 crypto_stream_xor(m,0,c,0,d,n,k);228 for (i = 0; i < 32; i++) m[i] = 0;229 return 0;230}231function set25519(r, a) {232 var i;233 for (i = 0; i < 16; i++) r[i] = a[i]|0;234}235function car25519(o) {236 var c;237 var i;238 for (i = 0; i < 16; i++) {239 o[i] += 65536;240 c = Math.floor(o[i] / 65536);241 o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0);242 o[i] -= (c * 65536);243 }244}245function sel25519(p, q, b) {246 var t, c = ~(b-1);247 for (var i = 0; i < 16; i++) {248 t = c & (p[i] ^ q[i]);249 p[i] ^= t;250 q[i] ^= t;251 }252}253function pack25519(o, n) {254 var i, j, b;255 var m = gf(), t = gf();256 for (i = 0; i < 16; i++) t[i] = n[i];257 car25519(t);258 car25519(t);259 car25519(t);260 for (j = 0; j < 2; j++) {261 m[0] = t[0] - 0xffed;262 for (i = 1; i < 15; i++) {263 m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);264 m[i-1] &= 0xffff;265 }266 m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);267 b = (m[15]>>16) & 1;268 m[14] &= 0xffff;269 sel25519(t, m, 1-b);270 }271 for (i = 0; i < 16; i++) {272 o[2*i] = t[i] & 0xff;273 o[2*i+1] = t[i]>>8;274 }275}276function neq25519(a, b) {277 var c = new Uint8Array(32), d = new Uint8Array(32);278 pack25519(c, a);279 pack25519(d, b);280 return crypto_verify_32(c, 0, d, 0);281}282function par25519(a) {283 var d = new Uint8Array(32);284 pack25519(d, a);285 return d[0] & 1;286}287function unpack25519(o, n) {288 var i;289 for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);290 o[15] &= 0x7fff;291}292function A(o, a, b) {293 var i;294 for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0;295}296function Z(o, a, b) {297 var i;298 for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0;299}300function M(o, a, b) {301 var i, j, t = new Float64Array(31);302 for (i = 0; i < 31; i++) t[i] = 0;303 for (i = 0; i < 16; i++) {304 for (j = 0; j < 16; j++) {305 t[i+j] += a[i] * b[j];306 }307 }308 for (i = 0; i < 15; i++) {309 t[i] += 38 * t[i+16];310 }311 for (i = 0; i < 16; i++) o[i] = t[i];312 car25519(o);313 car25519(o);314}315function S(o, a) {316 M(o, a, a);317}318function inv25519(o, i) {319 var c = gf();320 var a;321 for (a = 0; a < 16; a++) c[a] = i[a];322 for (a = 253; a >= 0; a--) {323 S(c, c);324 if(a !== 2 && a !== 4) M(c, c, i);325 }326 for (a = 0; a < 16; a++) o[a] = c[a];327}328function pow2523(o, i) {329 var c = gf();330 var a;331 for (a = 0; a < 16; a++) c[a] = i[a];332 for (a = 250; a >= 0; a--) {333 S(c, c);334 if(a !== 1) M(c, c, i);335 }336 for (a = 0; a < 16; a++) o[a] = c[a];337}338function crypto_scalarmult(q, n, p) {339 var z = new Uint8Array(32);340 var x = new Float64Array(80), r, i;341 var a = gf(), b = gf(), c = gf(),342 d = gf(), e = gf(), f = gf();343 for (i = 0; i < 31; i++) z[i] = n[i];344 z[31]=(n[31]&127)|64;345 z[0]&=248;346 unpack25519(x,p);347 for (i = 0; i < 16; i++) {348 b[i]=x[i];349 d[i]=a[i]=c[i]=0;350 }351 a[0]=d[0]=1;352 for (i=254; i>=0; --i) {353 r=(z[i>>>3]>>>(i&7))&1;354 sel25519(a,b,r);355 sel25519(c,d,r);356 A(e,a,c);357 Z(a,a,c);358 A(c,b,d);359 Z(b,b,d);360 S(d,e);361 S(f,a);362 M(a,c,a);363 M(c,b,e);364 A(e,a,c);365 Z(a,a,c);366 S(b,a);367 Z(c,d,f);368 M(a,c,_121665);369 A(a,a,d);370 M(c,c,a);371 M(a,d,f);372 M(d,b,x);373 S(b,e);374 sel25519(a,b,r);375 sel25519(c,d,r);376 }377 for (i = 0; i < 16; i++) {378 x[i+16]=a[i];379 x[i+32]=c[i];380 x[i+48]=b[i];381 x[i+64]=d[i];382 }383 var x32 = x.subarray(32);384 var x16 = x.subarray(16);385 inv25519(x32,x32);386 M(x16,x16,x32);387 pack25519(q,x16);388 return 0;389}390function crypto_scalarmult_base(q, n) {391 return crypto_scalarmult(q, n, _9);392}393function crypto_box_keypair(y, x) {394 randombytes(x, 32);395 return crypto_scalarmult_base(y, x);396}397function crypto_box_beforenm(k, y, x) {398 var s = new Uint8Array(32);399 crypto_scalarmult(s, x, y);400 return crypto_core_hsalsa20(k, _0, s, sigma);401}402var crypto_box_afternm = crypto_secretbox;403var crypto_box_open_afternm = crypto_secretbox_open;404function crypto_box(c, m, d, n, y, x) {405 var k = new Uint8Array(32);406 crypto_box_beforenm(k, y, x);407 return crypto_box_afternm(c, m, d, n, k);408}409function crypto_box_open(m, c, d, n, y, x) {410 var k = new Uint8Array(32);411 crypto_box_beforenm(k, y, x);412 return crypto_box_open_afternm(m, c, d, n, k);413}414function add64() {415 var a = 0, b = 0, c = 0, d = 0, m16 = 65535, l, h, i;416 for (i = 0; i < arguments.length; i++) {417 l = arguments[i].lo;418 h = arguments[i].hi;419 a += (l & m16); b += (l >>> 16);420 c += (h & m16); d += (h >>> 16);421 }422 b += (a >>> 16);423 c += (b >>> 16);424 d += (c >>> 16);425 return new u64((c & m16) | (d << 16), (a & m16) | (b << 16));426}427function shr64(x, c) {428 return new u64((x.hi >>> c), (x.lo >>> c) | (x.hi << (32 - c)));429}430function xor64() {431 var l = 0, h = 0, i;432 for (i = 0; i < arguments.length; i++) {433 l ^= arguments[i].lo;434 h ^= arguments[i].hi;435 }436 return new u64(h, l);437}438function R(x, c) {439 var h, l, c1 = 32 - c;440 if (c < 32) {441 h = (x.hi >>> c) | (x.lo << c1);442 l = (x.lo >>> c) | (x.hi << c1);443 } else if (c < 64) {444 h = (x.lo >>> c) | (x.hi << c1);445 l = (x.hi >>> c) | (x.lo << c1);446 }447 return new u64(h, l);448}449function Ch(x, y, z) {450 var h = (x.hi & y.hi) ^ (~x.hi & z.hi),451 l = (x.lo & y.lo) ^ (~x.lo & z.lo);452 return new u64(h, l);453}454function Maj(x, y, z) {455 var h = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi),456 l = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo);457 return new u64(h, l);458}459function Sigma0(x) { return xor64(R(x,28), R(x,34), R(x,39)); }460function Sigma1(x) { return xor64(R(x,14), R(x,18), R(x,41)); }461function sigma0(x) { return xor64(R(x, 1), R(x, 8), shr64(x,7)); }462function sigma1(x) { return xor64(R(x,19), R(x,61), shr64(x,6)); }463var K = [464 new u64(0x428a2f98, 0xd728ae22), new u64(0x71374491, 0x23ef65cd),465 new u64(0xb5c0fbcf, 0xec4d3b2f), new u64(0xe9b5dba5, 0x8189dbbc),466 new u64(0x3956c25b, 0xf348b538), new u64(0x59f111f1, 0xb605d019),467 new u64(0x923f82a4, 0xaf194f9b), new u64(0xab1c5ed5, 0xda6d8118),468 new u64(0xd807aa98, 0xa3030242), new u64(0x12835b01, 0x45706fbe),469 new u64(0x243185be, 0x4ee4b28c), new u64(0x550c7dc3, 0xd5ffb4e2),470 new u64(0x72be5d74, 0xf27b896f), new u64(0x80deb1fe, 0x3b1696b1),471 new u64(0x9bdc06a7, 0x25c71235), new u64(0xc19bf174, 0xcf692694),472 new u64(0xe49b69c1, 0x9ef14ad2), new u64(0xefbe4786, 0x384f25e3),473 new u64(0x0fc19dc6, 0x8b8cd5b5), new u64(0x240ca1cc, 0x77ac9c65),474 new u64(0x2de92c6f, 0x592b0275), new u64(0x4a7484aa, 0x6ea6e483),475 new u64(0x5cb0a9dc, 0xbd41fbd4), new u64(0x76f988da, 0x831153b5),476 new u64(0x983e5152, 0xee66dfab), new u64(0xa831c66d, 0x2db43210),477 new u64(0xb00327c8, 0x98fb213f), new u64(0xbf597fc7, 0xbeef0ee4),478 new u64(0xc6e00bf3, 0x3da88fc2), new u64(0xd5a79147, 0x930aa725),479 new u64(0x06ca6351, 0xe003826f), new u64(0x14292967, 0x0a0e6e70),480 new u64(0x27b70a85, 0x46d22ffc), new u64(0x2e1b2138, 0x5c26c926),481 new u64(0x4d2c6dfc, 0x5ac42aed), new u64(0x53380d13, 0x9d95b3df),482 new u64(0x650a7354, 0x8baf63de), new u64(0x766a0abb, 0x3c77b2a8),483 new u64(0x81c2c92e, 0x47edaee6), new u64(0x92722c85, 0x1482353b),484 new u64(0xa2bfe8a1, 0x4cf10364), new u64(0xa81a664b, 0xbc423001),485 new u64(0xc24b8b70, 0xd0f89791), new u64(0xc76c51a3, 0x0654be30),486 new u64(0xd192e819, 0xd6ef5218), new u64(0xd6990624, 0x5565a910),487 new u64(0xf40e3585, 0x5771202a), new u64(0x106aa070, 0x32bbd1b8),488 new u64(0x19a4c116, 0xb8d2d0c8), new u64(0x1e376c08, 0x5141ab53),489 new u64(0x2748774c, 0xdf8eeb99), new u64(0x34b0bcb5, 0xe19b48a8),490 new u64(0x391c0cb3, 0xc5c95a63), new u64(0x4ed8aa4a, 0xe3418acb),491 new u64(0x5b9cca4f, 0x7763e373), new u64(0x682e6ff3, 0xd6b2b8a3),492 new u64(0x748f82ee, 0x5defb2fc), new u64(0x78a5636f, 0x43172f60),493 new u64(0x84c87814, 0xa1f0ab72), new u64(0x8cc70208, 0x1a6439ec),494 new u64(0x90befffa, 0x23631e28), new u64(0xa4506ceb, 0xde82bde9),495 new u64(0xbef9a3f7, 0xb2c67915), new u64(0xc67178f2, 0xe372532b),496 new u64(0xca273ece, 0xea26619c), new u64(0xd186b8c7, 0x21c0c207),497 new u64(0xeada7dd6, 0xcde0eb1e), new u64(0xf57d4f7f, 0xee6ed178),498 new u64(0x06f067aa, 0x72176fba), new u64(0x0a637dc5, 0xa2c898a6),499 new u64(0x113f9804, 0xbef90dae), new u64(0x1b710b35, 0x131c471b),500 new u64(0x28db77f5, 0x23047d84), new u64(0x32caab7b, 0x40c72493),501 new u64(0x3c9ebe0a, 0x15c9bebc), new u64(0x431d67c4, 0x9c100d4c),502 new u64(0x4cc5d4be, 0xcb3e42b6), new u64(0x597f299c, 0xfc657e2a),503 new u64(0x5fcb6fab, 0x3ad6faec), new u64(0x6c44198c, 0x4a475817)504];505function crypto_hashblocks(x, m, n) {506 var z = [], b = [], a = [], w = [], t, i, j;507 for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8*i);508 var pos = 0;509 while (n >= 128) {510 for (i = 0; i < 16; i++) w[i] = dl64(m, 8*i+pos);511 for (i = 0; i < 80; i++) {512 for (j = 0; j < 8; j++) b[j] = a[j];513 t = add64(a[7], Sigma1(a[4]), Ch(a[4], a[5], a[6]), K[i], w[i%16]);514 b[7] = add64(t, Sigma0(a[0]), Maj(a[0], a[1], a[2]));515 b[3] = add64(b[3], t);516 for (j = 0; j < 8; j++) a[(j+1)%8] = b[j];517 if (i%16 === 15) {518 for (j = 0; j < 16; j++) {519 w[j] = add64(w[j], w[(j+9)%16], sigma0(w[(j+1)%16]), sigma1(w[(j+14)%16]));520 }521 }522 }523 for (i = 0; i < 8; i++) {524 a[i] = add64(a[i], z[i]);525 z[i] = a[i];526 }527 pos += 128;528 n -= 128;529 }530 for (i = 0; i < 8; i++) ts64(x, 8*i, z[i]);531 return n;532}533var iv = new Uint8Array([534 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,535 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,536 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,537 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,538 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,539 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,540 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,541 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79542]);543function crypto_hash(out, m, n) {544 var h = new Uint8Array(64), x = new Uint8Array(256);545 var i, b = n;546 for (i = 0; i < 64; i++) h[i] = iv[i];547 crypto_hashblocks(h, m, n);548 n %= 128;549 for (i = 0; i < 256; i++) x[i] = 0;550 for (i = 0; i < n; i++) x[i] = m[b-n+i];551 x[n] = 128;552 n = 256-128*(n<112?1:0);553 x[n-9] = 0;554 ts64(x, n-8, new u64((b / 0x20000000) | 0, b << 3));555 crypto_hashblocks(h, x, n);556 for (i = 0; i < 64; i++) out[i] = h[i];557 return 0;558}559function add(p, q) {560 var a = gf(), b = gf(), c = gf(),561 d = gf(), e = gf(), f = gf(),562 g = gf(), h = gf(), t = gf();563 Z(a, p[1], p[0]);564 Z(t, q[1], q[0]);565 M(a, a, t);566 A(b, p[0], p[1]);567 A(t, q[0], q[1]);568 M(b, b, t);569 M(c, p[3], q[3]);570 M(c, c, D2);571 M(d, p[2], q[2]);572 A(d, d, d);573 Z(e, b, a);574 Z(f, d, c);575 A(g, d, c);576 A(h, b, a);577 M(p[0], e, f);578 M(p[1], h, g);579 M(p[2], g, f);580 M(p[3], e, h);581}582function cswap(p, q, b) {583 var i;584 for (i = 0; i < 4; i++) {585 sel25519(p[i], q[i], b);586 }587}588function pack(r, p) {589 var tx = gf(), ty = gf(), zi = gf();590 inv25519(zi, p[2]);591 M(tx, p[0], zi);592 M(ty, p[1], zi);593 pack25519(r, ty);594 r[31] ^= par25519(tx) << 7;595}596function scalarmult(p, q, s) {597 var b, i;598 set25519(p[0], gf0);599 set25519(p[1], gf1);600 set25519(p[2], gf1);601 set25519(p[3], gf0);602 for (i = 255; i >= 0; --i) {603 b = (s[(i/8)|0] >> (i&7)) & 1;604 cswap(p, q, b);605 add(q, p);606 add(p, p);607 cswap(p, q, b);608 }609}610function scalarbase(p, s) {611 var q = [gf(), gf(), gf(), gf()];612 set25519(q[0], X);613 set25519(q[1], Y);614 set25519(q[2], gf1);615 M(q[3], X, Y);616 scalarmult(p, q, s);617}618function crypto_sign_keypair(pk, sk, seeded) {619 var d = new Uint8Array(64);620 var p = [gf(), gf(), gf(), gf()];621 var i;622 if (!seeded) randombytes(sk, 32);623 crypto_hash(d, sk, 32);624 d[0] &= 248;625 d[31] &= 127;626 d[31] |= 64;627 scalarbase(p, d);628 pack(pk, p);629 for (i = 0; i < 32; i++) sk[i+32] = pk[i];630 return 0;631}632var L = 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]);633function modL(r, x) {634 var carry, i, j, k;635 for (i = 63; i >= 32; --i) {636 carry = 0;637 for (j = i - 32, k = i - 12; j < k; ++j) {638 x[j] += carry - 16 * x[i] * L[j - (i - 32)];639 carry = Math.floor((x[j] + 128) / 256);640 x[j] -= carry * 256;641 }642 x[j] += carry;643 x[i] = 0;644 }645 carry = 0;646 for (j = 0; j < 32; j++) {647 x[j] += carry - (x[31] >> 4) * L[j];648 carry = x[j] >> 8;649 x[j] &= 255;650 }651 for (j = 0; j < 32; j++) x[j] -= carry * L[j];652 for (i = 0; i < 32; i++) {653 x[i+1] += x[i] >> 8;654 r[i] = x[i] & 255;655 }656}657function reduce(r) {658 var x = new Float64Array(64), i;659 for (i = 0; i < 64; i++) x[i] = r[i];660 for (i = 0; i < 64; i++) r[i] = 0;661 modL(r, x);662}663// Note: difference from C - smlen returned, not passed as argument.664function crypto_sign(sm, m, n, sk) {665 var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);666 var i, j, x = new Float64Array(64);667 var p = [gf(), gf(), gf(), gf()];668 crypto_hash(d, sk, 32);669 d[0] &= 248;670 d[31] &= 127;671 d[31] |= 64;672 var smlen = n + 64;673 for (i = 0; i < n; i++) sm[64 + i] = m[i];674 for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];675 crypto_hash(r, sm.subarray(32), n+32);676 reduce(r);677 scalarbase(p, r);678 pack(sm, p);679 for (i = 32; i < 64; i++) sm[i] = sk[i];680 crypto_hash(h, sm, n + 64);681 reduce(h);682 for (i = 0; i < 64; i++) x[i] = 0;683 for (i = 0; i < 32; i++) x[i] = r[i];684 for (i = 0; i < 32; i++) {685 for (j = 0; j < 32; j++) {686 x[i+j] += h[i] * d[j];687 }688 }689 modL(sm.subarray(32), x);690 return smlen;691}692function unpackneg(r, p) {693 var t = gf(), chk = gf(), num = gf(),694 den = gf(), den2 = gf(), den4 = gf(),695 den6 = gf();696 set25519(r[2], gf1);697 unpack25519(r[1], p);698 S(num, r[1]);699 M(den, num, D);700 Z(num, num, r[2]);701 A(den, r[2], den);702 S(den2, den);703 S(den4, den2);704 M(den6, den4, den2);705 M(t, den6, num);706 M(t, t, den);707 pow2523(t, t);708 M(t, t, num);709 M(t, t, den);710 M(t, t, den);711 M(r[0], t, den);712 S(chk, r[0]);713 M(chk, chk, den);714 if (neq25519(chk, num)) M(r[0], r[0], I);715 S(chk, r[0]);716 M(chk, chk, den);717 if (neq25519(chk, num)) return -1;718 if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);719 M(r[3], r[0], r[1]);720 return 0;721}722function crypto_sign_open(m, sm, n, pk) {723 var i;724 var t = new Uint8Array(32), h = new Uint8Array(64);725 var p = [gf(), gf(), gf(), gf()],726 q = [gf(), gf(), gf(), gf()];727 if (n < 64) return -1;728 if (unpackneg(q, pk)) return -1;729 for (i = 0; i < n; i++) m[i] = sm[i];730 for (i = 0; i < 32; i++) m[i+32] = pk[i];731 crypto_hash(h, m, n);732 reduce(h);733 scalarmult(p, q, h);734 scalarbase(q, sm.subarray(32));735 add(p, q);736 pack(t, p);737 n -= 64;738 if (crypto_verify_32(sm, 0, t, 0)) {739 for (i = 0; i < n; i++) m[i] = 0;740 return -1;741 }742 for (i = 0; i < n; i++) m[i] = sm[i + 64];743 return n;744}745var crypto_secretbox_KEYBYTES = 32,746 crypto_secretbox_NONCEBYTES = 24,747 crypto_secretbox_ZEROBYTES = 32,748 crypto_secretbox_BOXZEROBYTES = 16,749 crypto_scalarmult_BYTES = 32,750 crypto_scalarmult_SCALARBYTES = 32,751 crypto_box_PUBLICKEYBYTES = 32,752 crypto_box_SECRETKEYBYTES = 32,753 crypto_box_BEFORENMBYTES = 32,754 crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,755 crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,756 crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,757 crypto_sign_BYTES = 64,758 crypto_sign_PUBLICKEYBYTES = 32,759 crypto_sign_SECRETKEYBYTES = 64,760 crypto_sign_SEEDBYTES = 32,761 crypto_hash_BYTES = 64;762nacl.lowlevel = {763 crypto_core_hsalsa20: crypto_core_hsalsa20,764 crypto_stream_xor: crypto_stream_xor,765 crypto_stream: crypto_stream,766 crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,767 crypto_stream_salsa20: crypto_stream_salsa20,768 crypto_onetimeauth: crypto_onetimeauth,769 crypto_onetimeauth_verify: crypto_onetimeauth_verify,770 crypto_verify_16: crypto_verify_16,771 crypto_verify_32: crypto_verify_32,772 crypto_secretbox: crypto_secretbox,773 crypto_secretbox_open: crypto_secretbox_open,774 crypto_scalarmult: crypto_scalarmult,775 crypto_scalarmult_base: crypto_scalarmult_base,776 crypto_box_beforenm: crypto_box_beforenm,777 crypto_box_afternm: crypto_box_afternm,778 crypto_box: crypto_box,779 crypto_box_open: crypto_box_open,780 crypto_box_keypair: crypto_box_keypair,781 crypto_hash: crypto_hash,782 crypto_sign: crypto_sign,783 crypto_sign_keypair: crypto_sign_keypair,784 crypto_sign_open: crypto_sign_open,785 crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,786 crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,787 crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,788 crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,789 crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,790 crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,791 crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,792 crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,793 crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,794 crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,795 crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,796 crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,797 crypto_sign_BYTES: crypto_sign_BYTES,798 crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,799 crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,800 crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,801 crypto_hash_BYTES: crypto_hash_BYTES,802 gf: gf,803 D: D,804 L: L,805 pack25519: pack25519,806 unpack25519: unpack25519,807 M: M,808 A: A,809 S: S,810 Z: Z,811 pow2523: pow2523,812 add: add,813 set25519: set25519,814 modL: modL,815 scalarmult: scalarmult,816 scalarbase: scalarbase,817};818/* High-level API */819function checkLengths(k, n) {820 if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');821 if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size');822}823function checkBoxLengths(pk, sk) {824 if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size');825 if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size');826}827function checkArrayTypes() {828 for (var i = 0; i < arguments.length; i++) {829 if (!(arguments[i] instanceof Uint8Array))830 throw new TypeError('unexpected type, use Uint8Array');831 }832}833function cleanup(arr) {834 for (var i = 0; i < arr.length; i++) arr[i] = 0;835}836nacl.randomBytes = function(n) {837 var b = new Uint8Array(n);838 randombytes(b, n);839 return b;840};841nacl.secretbox = function(msg, nonce, key) {842 checkArrayTypes(msg, nonce, key);843 checkLengths(key, nonce);844 var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);845 var c = new Uint8Array(m.length);846 for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];847 crypto_secretbox(c, m, m.length, nonce, key);848 return c.subarray(crypto_secretbox_BOXZEROBYTES);849};850nacl.secretbox.open = function(box, nonce, key) {851 checkArrayTypes(box, nonce, key);852 checkLengths(key, nonce);853 var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);854 var m = new Uint8Array(c.length);855 for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];856 if (c.length < 32) return null;857 if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;858 return m.subarray(crypto_secretbox_ZEROBYTES);859};860nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;861nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;862nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;863nacl.scalarMult = function(n, p) {864 checkArrayTypes(n, p);865 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');866 if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');867 var q = new Uint8Array(crypto_scalarmult_BYTES);868 crypto_scalarmult(q, n, p);869 return q;870};871nacl.scalarMult.base = function(n) {872 checkArrayTypes(n);873 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');874 var q = new Uint8Array(crypto_scalarmult_BYTES);875 crypto_scalarmult_base(q, n);876 return q;877};878nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;879nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;880nacl.box = function(msg, nonce, publicKey, secretKey) {881 var k = nacl.box.before(publicKey, secretKey);882 return nacl.secretbox(msg, nonce, k);883};884nacl.box.before = function(publicKey, secretKey) {885 checkArrayTypes(publicKey, secretKey);886 checkBoxLengths(publicKey, secretKey);887 var k = new Uint8Array(crypto_box_BEFORENMBYTES);888 crypto_box_beforenm(k, publicKey, secretKey);889 return k;890};891nacl.box.after = nacl.secretbox;892nacl.box.open = function(msg, nonce, publicKey, secretKey) {893 var k = nacl.box.before(publicKey, secretKey);894 return nacl.secretbox.open(msg, nonce, k);895};896nacl.box.open.after = nacl.secretbox.open;897nacl.box.keyPair = function() {898 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);899 var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);900 crypto_box_keypair(pk, sk);901 return {publicKey: pk, secretKey: sk};902};903nacl.box.keyPair.fromSecretKey = function(secretKey) {904 checkArrayTypes(secretKey);905 if (secretKey.length !== crypto_box_SECRETKEYBYTES)906 throw new Error('bad secret key size');907 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);908 crypto_scalarmult_base(pk, secretKey);909 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};910};911nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;912nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;913nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;914nacl.box.nonceLength = crypto_box_NONCEBYTES;915nacl.box.overheadLength = nacl.secretbox.overheadLength;916nacl.sign = function(msg, secretKey) {917 checkArrayTypes(msg, secretKey);918 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)919 throw new Error('bad secret key size');920 var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);921 crypto_sign(signedMsg, msg, msg.length, secretKey);922 return signedMsg;923};924nacl.sign.open = function(signedMsg, publicKey) {925 checkArrayTypes(signedMsg, publicKey);926 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)927 throw new Error('bad public key size');928 var tmp = new Uint8Array(signedMsg.length);929 var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);930 if (mlen < 0) return null;931 var m = new Uint8Array(mlen);932 for (var i = 0; i < m.length; i++) m[i] = tmp[i];933 return m;934};935nacl.sign.detached = function(msg, secretKey) {936 var signedMsg = nacl.sign(msg, secretKey);937 var sig = new Uint8Array(crypto_sign_BYTES);938 for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];939 return sig;940};941nacl.sign.detached.verify = function(msg, sig, publicKey) {942 checkArrayTypes(msg, sig, publicKey);943 if (sig.length !== crypto_sign_BYTES)944 throw new Error('bad signature size');945 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)946 throw new Error('bad public key size');947 var sm = new Uint8Array(crypto_sign_BYTES + msg.length);948 var m = new Uint8Array(crypto_sign_BYTES + msg.length);949 var i;950 for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];951 for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];952 return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);953};954nacl.sign.keyPair = function() {955 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);956 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);957 crypto_sign_keypair(pk, sk);958 return {publicKey: pk, secretKey: sk};959};960nacl.sign.keyPair.fromSecretKey = function(secretKey) {961 checkArrayTypes(secretKey);962 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)963 throw new Error('bad secret key size');964 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);965 for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];966 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};967};968nacl.sign.keyPair.fromSeed = function(seed) {969 checkArrayTypes(seed);970 if (seed.length !== crypto_sign_SEEDBYTES)971 throw new Error('bad seed size');972 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);973 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);974 for (var i = 0; i < 32; i++) sk[i] = seed[i];975 crypto_sign_keypair(pk, sk, true);976 return {publicKey: pk, secretKey: sk};977};978nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;979nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;980nacl.sign.seedLength = crypto_sign_SEEDBYTES;981nacl.sign.signatureLength = crypto_sign_BYTES;982nacl.hash = function(msg) {983 checkArrayTypes(msg);984 var h = new Uint8Array(crypto_hash_BYTES);985 crypto_hash(h, msg, msg.length);986 return h;987};988nacl.hash.hashLength = crypto_hash_BYTES;989nacl.verify = function(x, y) {990 checkArrayTypes(x, y);991 // Zero length arguments are considered not equal.992 if (x.length === 0 || y.length === 0) return false;993 if (x.length !== y.length) return false;994 return (vn(x, 0, y, 0, x.length) === 0) ? true : false;995};996nacl.setPRNG = function(fn) {997 randombytes = fn;998};999(function() {1000 // Initialize PRNG if environment provides CSPRNG.1001 // If not, methods calling randombytes will throw.1002 var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;1003 if (crypto && crypto.getRandomValues) {1004 // Browsers.1005 var QUOTA = 65536;1006 nacl.setPRNG(function(x, n) {1007 var i, v = new Uint8Array(n);1008 for (i = 0; i < n; i += QUOTA) {1009 crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));1010 }1011 for (i = 0; i < n; i++) x[i] = v[i];1012 cleanup(v);1013 });1014 } else if (typeof require !== 'undefined') {1015 // Node.js.1016 crypto = require('crypto');1017 if (crypto && crypto.randomBytes) {1018 nacl.setPRNG(function(x, n) {1019 var i, v = crypto.randomBytes(n);1020 for (i = 0; i < n; i++) x[i] = v[i];1021 cleanup(v);1022 });1023 }1024 }1025})();...

Full Screen

Full Screen

server-crypto.ts

Source:server-crypto.ts Github

copy

Full Screen

1import { Config, CryptoNames, RegisteredCryptos } from '../shared/editable-config';2import { CRYPTO_EVENTS } from '../shared/events';3import cryptoApi from './crypto-api';4import { Database } from './mysql';5import { Methods } from './server-methods';6import { _U, _UFormat } from '../shared/translations';7import { CryptoPaymentInterface, CryptoPlayer, PlayerManager } from './cryptoplayer';8import { MarketCapManager } from './marketcap-counter';9export interface ICryptoApiResponse {10 asset_id: string;11 name: string;12 description: string;13 website: string;14 ethereum_contract_address: string;15 price: number;16 volume_24h: number;17 change_1h: number;18 change_24h: number;19 change_7d: number;20 total_supply: number;21 circulating_supply: number;22 max_supply: number;23 market_cap: number;24 fully_diluted_market_cap: number;25 status: string;26 created_at: Date;27 updated_at: Date;28}29onNet('crypto_nui_opened', (state: boolean) => {30 const Player = PlayerManager.getPlayerWithSource(global.source);31 Player && (Player.cryptoOpened = state);32});33onNet('crypto_deposit', (amount) => {34 const Player = PlayerManager.getPlayerWithSource(global.source);35 if (!Player) return;36 AquiverCrypto.player_deposit(Player, amount);37});38onNet('crypto_nui_withdraw', (amount) => {39 const Player = PlayerManager.getPlayerWithSource(global.source);40 if (!Player) return;41 AquiverCrypto.player_withdraw(Player, amount);42});43onNet('crypto_buy_crypto', (d) => {44 const Player = PlayerManager.getPlayerWithSource(global.source);45 if (!Player) return;46 AquiverCrypto.player_buyCrypto(Player, d.crypto, d.amount);47});48onNet('crypto_sell_crypto', (d) => {49 const Player = PlayerManager.getPlayerWithSource(global.source);50 if (!Player) return;51 AquiverCrypto.player_sellCrypto(Player, d.crypto, d.amount);52});53onNet('crypto_search_targetwallet', (targetId) => {54 const Player = PlayerManager.getPlayerWithSource(global.source);55 if (!Player) return;56 AquiverCrypto.searchTargetWallet(Player, targetId);57});58onNet('crypto_wallet_exist', (walletHash) => {59 const Player = PlayerManager.getPlayerWithSource(global.source);60 if (!Player) return;61 AquiverCrypto.WalletExist(Player, walletHash);62});63onNet('crypto_send_crypto_target', (d: { target: any | number; amount: any; crypto: any }) => {64 const { target, amount, crypto } = d;65 const Player = PlayerManager.getPlayerWithSource(global.source);66 if (!Player) return;67 AquiverCrypto.SendCryptoToTarget(Player, target, amount, crypto);68});69onNet('get_crypto_history', (d: { crypto: CryptoNames}) => {70 const { crypto } = d;71 const Player = PlayerManager.getPlayerWithSource(global.source);72 if(!Player) return;73 const history = AquiverCrypto.HistoryProxy.filter(a => a.crypto == crypto);74 Player.setCefVariable('cryptoHistory', history);75});76interface ITransactions {77 id?: number;78 walletHash: string;79 date: string;80 type: string;81 crypto: string;82 amount: number;83 price: number;84}85interface IHistory {86 id?: number;87 date: string;88 crypto: string;89 price: number;90}91export const AquiverCrypto = new (class _ {92 Cryptos: ICryptoApiResponse[] = [];93 /** Proxy declared later. */94 HistoryProxy: IHistory[] = [];95 /** Proxy declared later. */96 TransactionsProxy: ITransactions[] = [];97 constructor() {98 setInterval(() => {99 this.updateCryptoPrices().then(() => {100 PlayerManager.playersWithOpenedCrypto.forEach((P) => {101 P.setCefVariable('cryptoHistory', this.HistoryProxy);102 P.setCefVariable('cryptos', this.Cryptos);103 });104 });105 }, Config.updateInterval);106 }107 private historyProxyHandler(): ProxyHandler<IHistory[]> {108 return {109 get: (target, key) => {110 let val = target[key];111 if (typeof val === 'function') {112 if (['push', 'unshift'].includes(key as string)) {113 return (...args: IHistory[]) => {114 /** Apply the push here */115 val.apply(target, args);116 const pushedData: IHistory = args[0];117 Database.query(118 `INSERT INTO cryptohistory SET date = '${pushedData.date}', 119 crypto = '${pushedData.crypto}', 120 price = ${pushedData.price} ON DUPLICATE KEY UPDATE price = ${pushedData.price}`121 );122 /** Do not overflow the array */123 if (this.HistoryProxy.length > Config.maximumHistoryHold) {124 this.HistoryProxy.shift();125 this.clearHistoryCache();126 }127 };128 }129 }130 return (typeof val === 'function') ? val.bind(target) : val;131 },132 };133 }134 private transactionProxyHandler(): ProxyHandler<ITransactions[]> {135 return {136 get: (target, key) => {137 const val: Function = target[key];138 if (typeof val === 'function') {139 if (['push', 'unshift'].includes(key as string)) {140 return (...args: ITransactions[]) => {141 /** Apply the push here */142 val.apply(target, args);143 const pushedData: ITransactions = args[0];144 if (pushedData) {145 Database.query(146 `INSERT INTO crypto_transactions SET 147 walletHash = '${pushedData.walletHash}',148 date = '${Methods.stringCryptoDate()}',149 type = '${pushedData.type}',150 crypto = '${pushedData.crypto}',151 amount = ${pushedData.amount},152 price = ${pushedData.price}153 `154 );155 PlayerManager.playersWithOpenedCrypto.forEach((P) => {156 P.TriggerClient('crypto-add-transaction', pushedData);157 });158 }159 /** Do not overflow the array */160 if (this.TransactionsProxy.length > Config.maximumTransactionHold) {161 this.TransactionsProxy.shift();162 this.clearTransactionsCache();163 }164 };165 }166 return val.bind(target);167 }168 return val;169 },170 };171 }172 async __init__() {173 try {174 this.clearCache();175 console.info('[AQUIVER_CRYPTO - STARTED LOADING..]');176 console.time('[AQUIVER_CRYPTO - LOADED]');177 this.loadCryptoHistorical();178 this.loadCryptoTransactions();179 await this.updateCryptoPrices();180 console.timeEnd('[AQUIVER_CRYPTO - LOADED]');181 MarketCapManager.load();182 } catch (err) {183 console.error(err);184 }185 }186 SendCryptoToTarget(Player: CryptoPlayer, Target: string | CryptoPlayer, amount: any, crypto: CryptoNames) {187 if (Player.getCrypto(crypto) < amount) return Player.Notification(_U('not_enough_crypto'));188 amount = Methods.toDecimal(amount, 3);189 if (amount > 0 && typeof amount == 'number') {190 if (Methods.isHash(Target as string)) {191 const hash = Target as string;192 if (hash == Player.walletHash) return Player.Notification(_U('action_self'));193 /** If target player is online with wallet hash return the script and send the crypto. */194 const targetPlayer = PlayerManager.getPlayerByWalletHash(hash);195 if (targetPlayer) {196 this.SendCryptoToTarget(Player, targetPlayer, amount, crypto);197 return;198 }199 /** If target player is offline search in the database and send the crypto. */200 Database.query(`SELECT * FROM cryptoplayers WHERE walletHash = '${hash}'`, (err, rows, fields) => {201 if (err) return console.error(err);202 try {203 if (!rows || !rows[0]) return Player.Notification(_U('wallet_not_exist'));204 const data = rows[0];205 if (Player.getCrypto(crypto) < amount) return Player.Notification(_U('not_enough_crypto'));206 let mysqlCryptos = Methods.isValidJSON(data.cryptos) ? JSON.parse(data.cryptos) : {};207 if (typeof mysqlCryptos[crypto] === 'undefined') mysqlCryptos[crypto] = 0;208 mysqlCryptos[crypto] += amount;209 mysqlCryptos[crypto] = Methods.toDecimal(mysqlCryptos[crypto], 3);210 Database.query(`UPDATE cryptoplayers SET cryptos = '${JSON.stringify(mysqlCryptos)}' WHERE walletHash = '${hash}'`);211 Player.addOrRemoveCrypto(crypto, -amount);212 Player.Notification(_UFormat('crypto_payment_sent', amount, crypto));213 Player.PaymentsProxy.push({214 fromWallet: Player.walletHash,215 toWallet: rows[0].walletHash,216 date: Methods.stringCryptoDate(),217 amount,218 crypto,219 });220 Database.query(`INSERT INTO crypto_player_transactions SET 221 fromWallet = '${Player.walletHash}',222 toWallet = '${rows[0].walletHash}',223 date = '${Methods.stringCryptoDate()}',224 amount = ${amount},225 crypto = '${crypto}'226 `);227 } catch (err) {228 console.error(err);229 }230 });231 } else {232 /** If it was sent with CryptoPlayer class */233 if (Target instanceof CryptoPlayer) {234 if (Target == Player) return Player.Notification(_U('action_self'));235 Player.addOrRemoveCrypto(crypto, -amount);236 Target.addOrRemoveCrypto(crypto, +amount);237 Player.Notification(_UFormat('crypto_payment_sent', amount, crypto));238 let obj: CryptoPaymentInterface = {239 fromWallet: Player.walletHash,240 toWallet: Target.walletHash,241 date: Methods.stringCryptoDate(),242 amount,243 crypto,244 }245 Player.PaymentsProxy.push(obj);246 Target.PaymentsProxy.push(obj);247 Database.query(`INSERT INTO crypto_player_transactions SET 248 fromWallet = '${Player.walletHash}',249 toWallet = '${Target.walletHash}',250 date = '${Methods.stringCryptoDate()}',251 amount = ${amount},252 crypto = '${crypto}'253 `);254 } else {255 /** If it is a simple source ID. */256 const targetId = parseInt(Target as string);257 const T = PlayerManager.getPlayerWithSource(targetId);258 if (!T) return Player.Notification(_U('target_not_exist'));259 this.SendCryptoToTarget(Player, T, amount, crypto);260 }261 }262 }263 }264 WalletExist(Player: CryptoPlayer, walletHash: string) {265 Database.query(`SELECT COUNT(*) as total FROM cryptoplayers WHERE walletHash = '${walletHash}'`, (err, rows, fields) => {266 if (err) return console.error(err);267 try {268 let total = 0;269 if (rows && rows[0]) total = rows[0].total;270 Player.setCefVariable('targetWalletHash', total > 0 ? walletHash : 'Crypto wallet hash does not exist.');271 } catch (err) {272 console.error(err);273 }274 });275 }276 searchTargetWallet(Player: CryptoPlayer, targetId: any) {277 const Target = PlayerManager.getPlayerWithSource(targetId);278 if (!Target) {279 Player.Notification(_U('target_not_exist'));280 Player.setCefVariable('targetWalletHash', null);281 return;282 }283 Player.setCefVariable('targetWalletHash', Target.walletHash);284 }285 player_openCrypto(Player: CryptoPlayer) {286 Player.updatePlayer();287 Player.setCefVariable('marketCaps', MarketCapManager.MarketCapsObject);288 // Player.setCefVariable('cryptoHistory', this.HistoryProxy);289 Player.setCefVariable('transactions', this.TransactionsProxy);290 Player.setCefVariable('cryptos', this.Cryptos);291 Player.setCefVariable('feeAmount', Config.feeAmount);292 Player.setCefVariable('opened', true);293 }294 player_buyCrypto(Player: CryptoPlayer, crypto: CryptoNames, amount: any) {295 amount = Methods.toDecimal(amount, 3);296 if (amount > 0 && typeof amount === 'number') {297 const selectedCryptoData = this.Cryptos.find((a) => a.asset_id == crypto);298 if (!selectedCryptoData) return Player.Notification(_U('error_unknown_crypto'));299 const finalPrice = Methods.toDecimal(selectedCryptoData.price * amount, 3);300 if (finalPrice < 1) return Player.Notification(_U('bad_input'));301 if (Player.cryptobalance < finalPrice) return Player.Notification(_U('not_enough_cryptobalance'));302 Player.cryptobalance -= finalPrice;303 Player.addOrRemoveCrypto(crypto, +amount);304 Player.Notification(_UFormat('crypto_bought_success', amount, selectedCryptoData.name, finalPrice));305 this.createCryptoTransactionHistory(Player, 'BUY', crypto, amount, finalPrice);306 }307 }308 player_sellCrypto(Player: CryptoPlayer, crypto: CryptoNames, amount: number) {309 amount = Methods.toDecimal(amount, 3);310 if (amount > 0 && typeof amount === 'number') {311 const selectedCryptoData = this.Cryptos.find((a) => a.asset_id == crypto);312 if (selectedCryptoData) {313 const fee = (100 - Config.feeAmount) / 100;314 const finalPrice = Methods.toDecimal(selectedCryptoData.price * amount * fee, 3);315 if (finalPrice < 1) return Player.Notification(_U('bad_input'));316 if (Player.getCrypto(crypto) < amount) return Player.Notification(_UFormat('dont_have_much_crypto', selectedCryptoData.name));317 Player.cryptobalance += finalPrice;318 Player.addOrRemoveCrypto(crypto, -amount);319 Player.Notification(_UFormat('crypto_sold_success', amount, selectedCryptoData.name, finalPrice));320 this.createCryptoTransactionHistory(Player, 'SELL', crypto, amount, finalPrice);321 }322 }323 }324 player_withdraw(Player: CryptoPlayer, amount: any) {325 amount = Math.floor(amount);326 if (isNaN(amount) || amount < 1 || !amount) return Player.Notification(_U('bad_input'));327 if (Player.cryptobalance < amount) return Player.Notification(_U('not_enough_cryptobalance'));328 Player.bank += amount;329 Player.cryptobalance -= amount;330 }331 player_deposit(Player: CryptoPlayer, amount: any) {332 amount = Math.floor(amount);333 if (isNaN(amount) || amount < 1 || !amount) return;334 if (Player.bank < amount) return Player.Notification(_U('not_enough_bank'));335 Player.bank -= amount;336 Player.cryptobalance += amount;337 }338 private async createCryptoTransactionHistory(Player: CryptoPlayer, type: string, crypto: string, amount: number, price: number) {339 this.TransactionsProxy.push({340 amount,341 price,342 crypto,343 type,344 date: Methods.stringCryptoDate(),345 walletHash: Player.walletHash,346 });347 }348 private addCryptoHistory(date: string, crypto: string, price: number) {349 this.HistoryProxy.push({350 crypto,351 price,352 date,353 });354 }355 getCryptoPrice(crypto: CryptoNames) {356 let price = null;357 let f = this.Cryptos.find((a) => a.asset_id == crypto);358 if (f) price = f.price;359 return price;360 }361 private loadCryptoTransactions() {362 Database.query(`SELECT * FROM crypto_transactions`, (err, rows, fields) => {363 if (err) return console.error(err);364 if (!Array.isArray(rows)) return;365 if (rows.length > Config.maximumTransactionHold) rows.length = Config.maximumTransactionHold;366 this.TransactionsProxy = new Proxy(rows, this.transactionProxyHandler());367 });368 }369 private loadCryptoHistorical() {370 Database.query(`SELECT * FROM cryptohistory ORDER BY id ASC`, (err, rows, fields) => {371 if (err) return console.error(err);372 if (!Array.isArray(rows)) return;373 if (rows.length > Config.maximumHistoryHold) rows.length = Config.maximumHistoryHold;374 this.HistoryProxy = new Proxy(rows, this.historyProxyHandler());375 });376 }377 private clearHistoryCache() {378 Database.query(`SELECT COUNT(*) as total FROM cryptohistory`, (err, rows, fields) => {379 if (err) return console.error(err);380 const total = rows[0].total;381 if (total > Config.maximumHistoryHold) {382 const diff = total - Config.maximumHistoryHold;383 if (diff < 1) return;384 Database.query(`DELETE FROM cryptohistory LIMIT ${diff}`, (e) => {385 if (e) console.error(e);386 });387 }388 });389 }390 private clearTransactionsCache() {391 Database.query(`SELECT COUNT(*) as total FROM crypto_transactions`, (err, rows, fields) => {392 if (err) return console.error(err);393 const total = rows[0].total;394 if (total > Config.maximumTransactionHold) {395 const diff = total - Config.maximumTransactionHold;396 if (diff < 1) return;397 Database.query(`DELETE FROM crypto_transactions LIMIT ${diff}`, (e) => {398 if (e) console.error(e);399 });400 }401 });402 }403 /** Deleting the mysql tables if it overflowed the maximum config amount. */404 private clearCache() {405 this.clearHistoryCache();406 this.clearTransactionsCache();407 }408 private updateCryptoPrices() {409 return new Promise((resolve) => {410 this.Cryptos = [];411 const length = RegisteredCryptos.length - 1;412 const date = Methods.stringCryptoDate();413 RegisteredCryptos.forEach(async (crypto, index) => {414 await Methods.Wait(500 * index);415 cryptoApi416 .getPrice(crypto)417 .then((response) => {418 response.price = Methods.toDecimal(response.price);419 this.Cryptos.push(response);420 MarketCapManager.recalculateWithNewPrices(crypto, response.price);421 this.addCryptoHistory(date, crypto, response.price);422 })423 .catch((err) => {424 console.error(`Crypto could not be loaded. [${crypto}]`);425 })426 .finally(() => {427 if (length == index) resolve(true);428 });429 });430 });431 }...

Full Screen

Full Screen

marketcap-counter.ts

Source:marketcap-counter.ts Github

copy

Full Screen

1import { CryptoNames, RegisteredCryptos } from "../shared/editable-config";2import { PlayerManager } from "./cryptoplayer";3import { Database } from "./mysql";4import { AquiverCrypto } from "./server-crypto";5import { Methods } from "./server-methods";6export class MarketCapManager7{8 /** Holds up every amount of crypto that the player's has. */9 static CryptoAmounts = new Map<CryptoNames, number>();10 /** Cryptos with prices * cryptoamount */11 static MarketCaps = new Map<CryptoNames, number>();12 static load()13 {14 Database.query(`SELECT cryptos FROM cryptoplayers`, (err, rows, fields) =>15 {16 if (err) return console.error(err);17 if (!rows || !Array.isArray(rows)) return;18 rows.forEach((a, index) =>19 {20 if (!Methods.isValidJSON(a.cryptos)) return;21 a.cryptos = JSON.parse(a.cryptos);22 for (const crypto in a.cryptos)23 {24 const amount = a.cryptos[crypto];25 if (amount <= 0) return;26 this.addOrRemoveCryptoAmount(crypto as CryptoNames, +amount);27 }28 });29 });30 }31 static getAllCryptoAmount(crypto: CryptoNames)32 {33 let v = 0;34 if (this.CryptoAmounts.has(crypto)) v = this.CryptoAmounts.get(crypto);35 return v;36 }37 /** Recalculate the marketcaps when the crypto price gets updated from the API. */38 static recalculateWithNewPrices(crypto: CryptoNames, withPrice?: number)39 {40 let price = withPrice;41 if (price === undefined) price = AquiverCrypto.getCryptoPrice(crypto);42 if (price === null) return;43 if(!this.MarketCaps.has(crypto)) this.MarketCaps.set(crypto, 0);44 const cryptoAmount = this.getAllCryptoAmount(crypto);45 if(cryptoAmount > 0) {46 this.MarketCaps.set(crypto, Methods.toDecimal(price * cryptoAmount))47 }48 }49 static addOrRemoveCryptoAmount(crypto: CryptoNames, cryptoAmount: number)50 {51 if (!this.CryptoAmounts.has(crypto)) this.CryptoAmounts.set(crypto, 0);52 let newValue = this.getAllCryptoAmount(crypto) + cryptoAmount;53 if (newValue < 0) newValue = 0;54 this.CryptoAmounts.set(crypto, newValue);55 /** Update crypto marketcap with price */56 if (!this.MarketCaps.has(crypto)) this.MarketCaps.set(crypto, 0);57 const cryptoPrice = AquiverCrypto.getCryptoPrice(crypto);58 if (cryptoPrice !== null)59 {60 this.MarketCaps.set(crypto, Methods.toDecimal(newValue * cryptoPrice));61 PlayerManager.playersWithOpenedCrypto.forEach(P =>62 {63 P.setCefVariable('marketCaps', this.MarketCapsObject);64 });65 }66 }67 static get MarketCapsObject()68 {69 return Object.fromEntries(this.MarketCaps);70 }...

Full Screen

Full Screen

crypto.ts

Source:crypto.ts Github

copy

Full Screen

1import {2 createEntityAdapter, createSlice,3} from '@reduxjs/toolkit';4import { coreReducers, coreExtraReducers } from '@amnis/core/reducers';5import { apiExtraReducers } from '@amnis/api/reducers';6import { Crypto, cryptoKey } from '@amnis/core/crypto';7import type { CryptoMeta } from './crypto.types';8/**9 * RTK crypto adapter.10 * Manages the normalized entities.11 */12export const cryptoAdapter = createEntityAdapter<Crypto>({13 /**14 * Identifiers are stored in the `$id` property.15 */16 selectId: (entity) => entity.$id,17 /**18 * TODO: A sort comparer other than `$id` is ideal.19 */20 // sortComparer: (a, b) => a.name.localeCompare(b.name),21});22/**23 * Initialized crypto state with meta information.24 */25export const cryptoInitialState = cryptoAdapter.getInitialState<CryptoMeta>({26 active: null,27 focused: null,28 selection: [],29});30/**31 * RTK Crypto Slice32 */33export const cryptoSlice = createSlice({34 name: cryptoKey,35 initialState: cryptoInitialState,36 reducers: {37 /**38 * Common reducers and actions.39 */40 ...coreReducers<Crypto>(cryptoKey, cryptoAdapter),41 },42 extraReducers: (builder) => {43 /**44 * Required: Enables mutations from core actions.45 */46 coreExtraReducers(cryptoKey, cryptoAdapter, builder);47 /**48 * Required: Enables mutations from api requests.49 */50 apiExtraReducers(cryptoKey, cryptoAdapter, builder);51 },52});53/**54 * Crypto redux reducer.55 */56export const cryptoReducer = cryptoSlice.reducer;57/**58 * Crypto redux actions.59 */60export const cryptoActions = cryptoSlice.actions;61/**62 * Crypto redux selectors.63 */64export const cryptoSelectors = {65 /**66 * Gets entity selectors.67 */68 ...cryptoAdapter.getSelectors<{69 [cryptoKey]: typeof cryptoInitialState;70 }>((state) => state[cryptoKey]),71};72/**73 * Crypto redux selector keys.74 */75export type CryptoSelector = Extract<keyof typeof cryptoSelectors, string>;76/**77 * Export the slice as default.78 */...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var crypto = require('crypto');2var fs = require('fs');3var bestCrypt = require('bestcrypt');4var bestCryptPath = "C:\\Program Files\\Jetico\\BestCrypt\\bc.exe";5var password = "password";6var input = "C:\\Users\\Public\\Documents\\test.txt";7var output = "C:\\Users\\Public\\Documents\\test.txt.bcf";8var args = ["/q", "/p", password, "/f", input, "/o", output];9bestCrypt.encrypt(bestCryptPath, args, function(err, stdout, stderr){10 if (err) {11 console.log('error: ' + err);12 return;13 }14 console.log('stdout: ' + stdout);15 console.log('stderr: ' + stderr);16});17var crypto = require('crypto');18var fs = require('fs');19var bestCrypt = require('bestcrypt');20var bestCryptPath = "C:\\Program Files\\Jetico\\BestCrypt\\bc.exe";21var password = "password";22var input = "C:\\Users\\Public\\Documents\\test.txt.bcf";23var output = "C:\\Users\\Public\\Documents\\test.txt";24var args = ["/q", "/p", password, "/f", input, "/o", output];25bestCrypt.decrypt(bestCryptPath, args, function(err, stdout, stderr){26 if (err) {27 console.log('error: ' + err);28 return;29 }30 console.log('stdout: ' + stdout);31 console.log('stderr: ' + stderr);32});33var crypto = require('crypto');34var fs = require('fs');35var bestCrypt = require('bestcrypt');36var bestCryptPath = "C:\\Program Files\\Jetico\\BestCrypt\\bc.exe";37var password = "password";38var input = "C:\\Users\\Public\\Documents\\test.txt";39var output = "C:\\Users\\Public\\Documents\\test.txt.bcf";40var args = ["/q", "/p", password, "/f", input, "/o", output];41bestCrypt.encrypt(bestCryptPath, args, function(err, stdout, stderr){42 if (err) {43 console.log('error: ' + err);44 return;45 }

Full Screen

Using AI Code Generation

copy

Full Screen

1var crypto = require('crypto');2var fs = require('fs');3var bestCrypt = require('bestcrypt');4var key = fs.readFileSync('./key.txt');5var data = fs.readFileSync('./test.txt');6var encrypted = bestCrypt.encrypt(data, key);7var decrypted = bestCrypt.decrypt(encrypted, key);8console.log('encrypted', encrypted);9console.log('decrypted', decrypted);10var crypto = require('crypto');11var fs = require('fs');12var bestCrypt = require('bestcrypt');13var key = bestCrypt.generateKey(256);14fs.writeFileSync('./key.txt', key);15var crypto = require('crypto');16var fs = require('fs');17var bestCrypt = require('bestcrypt');18var data = bestCrypt.generateData(256);19fs.writeFileSync('./test.txt', data);20var crypto = require('crypto');21var fs = require('fs');22var bestCrypt = require('bestcrypt');23var key = bestCrypt.generateKey(256);24fs.writeFileSync('./key.txt', key);25var crypto = require('crypto');26var fs = require('fs');27var bestCrypt = require('bestcrypt');28var data = bestCrypt.generateData(256);29fs.writeFileSync('./test.txt', data);30var crypto = require('crypto');31var fs = require('fs');32var bestCrypt = require('bestcrypt');33var key = fs.readFileSync('./key.txt');34var data = fs.readFileSync('./test.txt');35var encrypted = bestCrypt.encrypt(data, key);36var decrypted = bestCrypt.decrypt(encrypted, key);37console.log('encrypted', encrypted);38console.log('decrypted', decrypted);

Full Screen

Using AI Code Generation

copy

Full Screen

1var bestcrypt = require('bestcrypt');2var fs = require('fs');3var password = "test";4var input = fs.readFileSync('test.txt');5var output = bestcrypt.encrypt(password, input);6fs.writeFileSync('test.enc', output);7var output2 = bestcrypt.decrypt(password, output);8fs.writeFileSync('test2.txt', output2);

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Best automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful