增加client登录模式,增加登录日志

This commit is contained in:
CounterFire2023 2023-08-17 15:58:36 +08:00
parent d1f3fed196
commit 099f1a8135
26 changed files with 1400 additions and 375 deletions

View File

@ -42,4 +42,7 @@ PAY_TRANSFER_CB_URL='http://127.0.0.1:3007/api/internal/update_task'
HASH_SALT='iG4Rpsa)6U31$H#^T85$^^3'
# 游戏服, 支付上报地址
GAME_PAY_CB_URL=https://game2006api-test.kingsome.cn/webapp/index.php?c=Shop&a=buyGoodsDirect
GAME_PAY_CB_URL=https://game2006api-test.kingsome.cn/webapp/index.php?c=Shop&a=buyGoodsDirect
# client登录时,验证用户数据的private key
WALLET_CLIENT_SK='38d9baa24aaea6f87a1caa51f588b0c9578368a1cb00b1639eb9f450b6cada00'

View File

@ -1,9 +1,48 @@
API_PORT=3086
API_PORT=3007
API_HOST=0.0.0.0
API_TOKEN_SECRET=sdf(**&*&xx2214
API_TOKEN_SECRET_PRIVATE=MC4CAQAwBQYDK2VwBCIEIKdK/eFQ2+Q/ml4ruDAItNIwGnQMQm76UX0uecrna7V5
API_TOKEN_SECRET_PUBLIC=MCowBQYDK2VwAyEAySgE/YiiI2fzpXaco+OWeDAKymEoqqLYYb6RKOEU1n8=
API_TOKEN_EXPIRESIN=1d
GOOGLE_OAUTH_CLIENT="53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleusercontent.com"
GOOGLE_OAUTH_CLIENT2="53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com"
GOOGLE_OAUTH_CLIENT_IOS="53206975661-qan0rnefniegjv53ohild375pv0p7ekd.apps.googleusercontent.com"
DB_MAIN=mongodb://localhost/wallet-production
DB_MAIN=mongodb://192.168.100.22/wallet-development
EMAIL_VERIFY_URL="https://wallet.cebggame.com"
EMAIL_SERVER='http://127.0.0.1:3087'
ALCHEMY_APPID="f83Is2y7L425rxl8"
ALCHEMY_APP_SECRET="4Yn8RkxDXN71Q3p0"
# ALCHEMY_API_BASE="https://openapi-test.alchemypay.org"
# ALCHEMY_PAGE_BASE="https://ramptest.alchemypay.org"
ALCHEMY_API_BASE="http://127.0.0.1:3009"
ALCHEMY_PAGE_BASE="http://127.0.0.1:3009/pay_page"
ALCHEMY_PAY_CB_URL="https://wallet.cebggame.com"
CHAIN_CLIENT_URL=http://127.0.0.1:3006
#cryptocompare api key from metamask^_^
CRYPTOCOMPARE_API_KEY=d1ec8cd68228095debc9db2dca45771b905ce1f27f522ebfef025c236f4aef3b
# alchemy 相关配置
AVAILABLE_NETWORK=agor
AVAILABLE_TOKENS=cec|ceg
AGOR_CHAIN_ID=421163
AGOR_DEV_CEC_ADDRESS='0x8dd1439E0C3254b4543d6D68b3C0C891E5Bd2eCE'
AGOR_DEV_CEG_ADDRESS='0x2C7221588D4FBac2585D71618CD540e74c7413B8'
AGOR_RELEASE_CEC_ADDRESS='0x2C7221588D4FBac2585D71618CD540e74c7413B8'
AGOR_RELEASE_CEG_ADDRESS='0x2C7221588D4FBac2585D71618CD540e74c7413B8'
AGOR_WALLET='0x50A8e60041A206AcaA5F844a1104896224be6F39'
# 链端转账回调地址
PAY_TRANSFER_CB_URL='http://127.0.0.1:3007/api/internal/update_task'
# 链端回调hash的ket
HASH_SALT='iG4Rpsa)6U31$H#^T85$^^3'
# 游戏服, 支付上报地址
GAME_PAY_CB_URL=https://game2006api-test.kingsome.cn/webapp/index.php?c=Shop&a=buyGoodsDirect
# client登录时,验证用户数据的private key
WALLET_CLIENT_SK='38d9baa24aaea6f87a1caa51f588b0c9578368a1cb00b1639eb9f450b6cada00'

View File

@ -30,13 +30,14 @@
"mongoose-findorcreate": "^3.0.0",
"nanoid": "^3.1.23",
"node-schedule": "^2.1.1",
"rustwallet": "file:./rustwallet",
"tracer": "^1.1.6",
"verify-apple-id-token": "^3.0.0"
},
"devDependencies": {
"@typegoose/typegoose": "^9.12.1",
"@types/node-schedule": "^2.1.0",
"@types/dotenv": "^8.2.0",
"@types/node-schedule": "^2.1.0",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.25.0",

1
rustwallet/README.md Normal file
View File

@ -0,0 +1 @@
# Rust版的钱包

12
rustwallet/package-lock.json generated Normal file
View File

@ -0,0 +1,12 @@
{
"name": "rustwallet",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rustwallet",
"version": "0.1.0"
}
}
}

11
rustwallet/package.json Normal file
View File

@ -0,0 +1,11 @@
{
"name": "rustwallet",
"version": "0.1.0",
"files": [
"rustwallet_bg.wasm",
"rustwallet.js",
"rustwallet.d.ts"
],
"main": "rustwallet.js",
"types": "rustwallet.d.ts"
}

106
rustwallet/rustwallet.d.ts vendored Normal file
View File

@ -0,0 +1,106 @@
/* tslint:disable */
/* eslint-disable */
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
export function get_public_key(msg_key: string, master_key: string, second_key: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
export function generate_sec_key(msg_key: string, master_key: string, second_key: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
export function sign(msg_key: string, master_key: string, second_key: string, msg: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
export function sign_for_tran(msg_key: string, master_key: string, second_key: string, msg: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
export function wget_address(msg_key: string, master_key: string, second_key: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
export function wencrypt(msg_key: string, master_key: string, second_key: string, msg: string): string;
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
export function wdecrypt(msg_key: string, master_key: string, second_key: string, msg: string): string;
/**
* @param {string} content
* @param {string} key
* @returns {string}
*/
export function aes_encrypt(content: string, key: string): string;
/**
* @param {string} content
* @param {string} key
* @returns {string}
*/
export function aes_decrypt(content: string, key: string): string;
/**
* @param {string} pk
* @param {string} msg
* @returns {string}
*/
export function rencrypt(pk: string, msg: string): string;
/**
* @param {string} sk
* @param {string} msg
* @returns {string}
*/
export function rdecrypt(sk: string, msg: string): string;
/**
* @param {string} content
* @returns {string}
*/
export function generate_qr(content: string): string;
/**
* @param {string} content
* @returns {string}
*/
export function hex_deflate(content: string): string;
/**
* @param {string} content
* @returns {string}
*/
export function hex_inflate(content: string): string;
/**
* @param {string} pass
* @param {string} salt
* @returns {string}
*/
export function password_hash(pass: string, salt: string): string;
/**
* @param {string} pass
* @param {string} pass_hash
* @returns {boolean}
*/
export function password_verify(pass: string, pass_hash: string): boolean;

642
rustwallet/rustwallet.js Normal file
View File

@ -0,0 +1,642 @@
let imports = {};
imports['__wbindgen_placeholder__'] = module.exports;
let wasm;
const { TextDecoder, TextEncoder } = require(`util`);
const heap = new Array(32).fill(undefined);
heap.push(undefined, null, true, false);
function getObject(idx) { return heap[idx]; }
let heap_next = heap.length;
function dropObject(idx) {
if (idx < 36) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
let cachedUint8Memory0 = new Uint8Array();
function getUint8Memory0() {
if (cachedUint8Memory0.byteLength === 0) {
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
let WASM_VECTOR_LEN = 0;
let cachedTextEncoder = new TextEncoder('utf-8');
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length);
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len);
const mem = getUint8Memory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3);
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
let cachedInt32Memory0 = new Int32Array();
function getInt32Memory0() {
if (cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
module.exports.get_public_key = function(msg_key, master_key, second_key) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
wasm.get_public_key(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
module.exports.generate_sec_key = function(msg_key, master_key, second_key) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
wasm.generate_sec_key(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
module.exports.sign = function(msg_key, master_key, second_key, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
const ptr3 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len3 = WASM_VECTOR_LEN;
wasm.sign(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
module.exports.sign_for_tran = function(msg_key, master_key, second_key, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
const ptr3 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len3 = WASM_VECTOR_LEN;
wasm.sign_for_tran(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @returns {string}
*/
module.exports.wget_address = function(msg_key, master_key, second_key) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
wasm.wget_address(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
module.exports.wencrypt = function(msg_key, master_key, second_key, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
const ptr3 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len3 = WASM_VECTOR_LEN;
wasm.wencrypt(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} msg_key
* @param {string} master_key
* @param {string} second_key
* @param {string} msg
* @returns {string}
*/
module.exports.wdecrypt = function(msg_key, master_key, second_key, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(msg_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(master_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ptr2 = passStringToWasm0(second_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len2 = WASM_VECTOR_LEN;
const ptr3 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len3 = WASM_VECTOR_LEN;
wasm.wdecrypt(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} content
* @param {string} key
* @returns {string}
*/
module.exports.aes_encrypt = function(content, key) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
wasm.aes_encrypt(retptr, ptr0, len0, ptr1, len1);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} content
* @param {string} key
* @returns {string}
*/
module.exports.aes_decrypt = function(content, key) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
wasm.aes_decrypt(retptr, ptr0, len0, ptr1, len1);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} pk
* @param {string} msg
* @returns {string}
*/
module.exports.rencrypt = function(pk, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(pk, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
wasm.rencrypt(retptr, ptr0, len0, ptr1, len1);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} sk
* @param {string} msg
* @returns {string}
*/
module.exports.rdecrypt = function(sk, msg) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(sk, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
wasm.rdecrypt(retptr, ptr0, len0, ptr1, len1);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} content
* @returns {string}
*/
module.exports.generate_qr = function(content) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
wasm.generate_qr(retptr, ptr0, len0);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} content
* @returns {string}
*/
module.exports.hex_deflate = function(content) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
wasm.hex_deflate(retptr, ptr0, len0);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} content
* @returns {string}
*/
module.exports.hex_inflate = function(content) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
wasm.hex_inflate(retptr, ptr0, len0);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} pass
* @param {string} salt
* @returns {string}
*/
module.exports.password_hash = function(pass, salt) {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(pass, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(salt, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
wasm.password_hash(retptr, ptr0, len0, ptr1, len1);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(r0, r1);
}
};
/**
* @param {string} pass
* @param {string} pass_hash
* @returns {boolean}
*/
module.exports.password_verify = function(pass, pass_hash) {
const ptr0 = passStringToWasm0(pass, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(pass_hash, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ret = wasm.password_verify(ptr0, len0, ptr1, len1);
return ret !== 0;
};
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
module.exports.__wbg_log_49bdec560ec4ae91 = function(arg0, arg1) {
console.log(getStringFromWasm0(arg0, arg1));
};
module.exports.__wbg_randomFillSync_065afffde01daa66 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2));
}, arguments) };
module.exports.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
module.exports.__wbg_getRandomValues_b99eec4244a475bb = function() { return handleError(function (arg0, arg1) {
getObject(arg0).getRandomValues(getObject(arg1));
}, arguments) };
module.exports.__wbg_process_0cc2ada8524d6f83 = function(arg0) {
const ret = getObject(arg0).process;
return addHeapObject(ret);
};
module.exports.__wbindgen_is_object = function(arg0) {
const val = getObject(arg0);
const ret = typeof(val) === 'object' && val !== null;
return ret;
};
module.exports.__wbg_versions_c11acceab27a6c87 = function(arg0) {
const ret = getObject(arg0).versions;
return addHeapObject(ret);
};
module.exports.__wbg_node_7ff1ce49caf23815 = function(arg0) {
const ret = getObject(arg0).node;
return addHeapObject(ret);
};
module.exports.__wbindgen_is_string = function(arg0) {
const ret = typeof(getObject(arg0)) === 'string';
return ret;
};
module.exports.__wbg_crypto_2036bed7c44c25e7 = function(arg0) {
const ret = getObject(arg0).crypto;
return addHeapObject(ret);
};
module.exports.__wbg_msCrypto_a21fc88caf1ecdc8 = function(arg0) {
const ret = getObject(arg0).msCrypto;
return addHeapObject(ret);
};
module.exports.__wbg_static_accessor_NODE_MODULE_cf6401cc1091279e = function() {
const ret = module;
return addHeapObject(ret);
};
module.exports.__wbg_require_a746e79b322b9336 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
module.exports.__wbg_newnoargs_b5b063fc6c2f0376 = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
module.exports.__wbg_call_97ae9d8645dc388b = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
module.exports.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
module.exports.__wbg_self_6d479506f72c6a71 = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
module.exports.__wbg_window_f2557cc78490aceb = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
module.exports.__wbg_globalThis_7f206bda628d5286 = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
module.exports.__wbg_global_ba75c50d1cf384f4 = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
module.exports.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
return ret;
};
module.exports.__wbg_buffer_3f3d764d4747d564 = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
};
module.exports.__wbg_new_8c3f0052272a457a = function(arg0) {
const ret = new Uint8Array(getObject(arg0));
return addHeapObject(ret);
};
module.exports.__wbg_set_83db9690f9353e79 = function(arg0, arg1, arg2) {
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
};
module.exports.__wbg_length_9e1ae1900cb0fbd5 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
module.exports.__wbg_newwithlength_f5933855e4f48a19 = function(arg0) {
const ret = new Uint8Array(arg0 >>> 0);
return addHeapObject(ret);
};
module.exports.__wbg_subarray_58ad4efbb5bcb886 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
return addHeapObject(ret);
};
module.exports.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
module.exports.__wbindgen_memory = function() {
const ret = wasm.memory;
return addHeapObject(ret);
};
const path = require('path').join(__dirname, 'rustwallet_bg.wasm');
const bytes = require('fs').readFileSync(path);
const wasmModule = new WebAssembly.Module(bytes);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
wasm = wasmInstance.exports;
module.exports.__wasm = wasm;

Binary file not shown.

28
rustwallet/rustwallet_bg.wasm.d.ts vendored Normal file
View File

@ -0,0 +1,28 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export function get_public_key(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
export function generate_sec_key(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
export function sign(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void;
export function sign_for_tran(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void;
export function wget_address(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
export function wencrypt(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void;
export function wdecrypt(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void;
export function aes_encrypt(a: number, b: number, c: number, d: number, e: number): void;
export function aes_decrypt(a: number, b: number, c: number, d: number, e: number): void;
export function rencrypt(a: number, b: number, c: number, d: number, e: number): void;
export function rdecrypt(a: number, b: number, c: number, d: number, e: number): void;
export function generate_qr(a: number, b: number, c: number): void;
export function hex_deflate(a: number, b: number, c: number): void;
export function hex_inflate(a: number, b: number, c: number): void;
export function password_hash(a: number, b: number, c: number, d: number, e: number): void;
export function password_verify(a: number, b: number, c: number, d: number): number;
export function rustsecp256k1_v0_7_0_context_create(a: number): number;
export function rustsecp256k1_v0_7_0_context_destroy(a: number): void;
export function rustsecp256k1_v0_7_0_default_illegal_callback_fn(a: number, b: number): void;
export function rustsecp256k1_v0_7_0_default_error_callback_fn(a: number, b: number): void;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_malloc(a: number): number;
export function __wbindgen_realloc(a: number, b: number, c: number): number;
export function __wbindgen_free(a: number, b: number): void;
export function __wbindgen_exn_store(a: number): void;

View File

@ -3,6 +3,7 @@ import { role, router } from 'decorators/router'
import verifyAppleToken from 'verify-apple-id-token'
import { Account, PlatEnum } from 'modules/Account'
import axios from 'axios'
import logger from 'logger/logger'
var https = require('follow-redirects').https
const CLIENT_ID_DEBUG = 'com.jc.tebg'
@ -21,7 +22,7 @@ class AppleController extends BaseController {
@router('post /wallet/login/apple')
async checkGoogleJwt(req, res) {
const { token } = req.params
logger.db('login', req)
const payload = await verifyAppleToken({
idToken: token,
clientId: [CLIENT_ID_DEBUG, CLIENT_ID_RELEASE, CLIEND_ID_ANDROID],
@ -33,6 +34,10 @@ class AppleController extends BaseController {
if (payload.locale) data.locale = payload.locale
if (payload.name) data.nickname = payload.name
if (payload.picture) data.avatar = payload.picture
const { api_platform } = req.headers
if (api_platform) {
data.platform = api_platform
}
let user = await Account.insertOrUpdate({ plat: PlatEnum.APPLE, openId }, data)
const ztoken = await res.jwtSign({
id: user.id,

View File

@ -0,0 +1,47 @@
import BaseController, { ROLE_ANON } from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import logger from 'logger/logger'
import { Account, PlatEnum } from 'modules/Account'
import * as wasm from 'rustwallet'
import { isUUID } from 'utils/string.util'
const CLIENT_SUFFIX = '_clientid'
function checkClientId(clientId: string) {
if (!clientId) {
return false
}
if (!clientId.endsWith(CLIENT_SUFFIX)) {
return false
}
const id = clientId.slice(0, clientId.length - CLIENT_SUFFIX.length)
return isUUID(id)
}
class ClientController extends BaseController {
@role(ROLE_ANON)
@router('post /wallet/login/client')
async clientLogin(req, res) {
const { code } = req.params
const { api_platform } = req.headers
logger.db('login', req)
if (!code) {
throw new ZError(11, 'param missing')
}
const sk = process.env.WALLET_CLIENT_SK
let codeDecrypto = wasm.rdecrypt(sk, code)
if (!checkClientId(codeDecrypto)) {
throw new ZError(12, 'param invalid')
}
const openId = codeDecrypto.slice(0, codeDecrypto.length - CLIENT_SUFFIX.length)
logger.info('clientLogin', openId)
let user = await Account.insertOrUpdate({ plat: PlatEnum.CLIENT, openId }, { platform: api_platform })
const ztoken = await res.jwtSign({
id: user.id,
openid: user.openId,
version: user.accountVersion || 0,
plat: PlatEnum.CLIENT,
})
return { token: ztoken }
}
}

View File

@ -1,6 +1,7 @@
import BaseController, { ROLE_ANON } from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import logger from 'logger/logger'
import { Account, PlatEnum } from 'modules/Account'
import { FACEBOOK_APP_ID, fetchUserInfo, verifyFbUserAccessToken } from 'providers/facebook.provider'
@ -9,6 +10,7 @@ class FacebookController extends BaseController {
@router('post /wallet/login/facebook')
async checkFacebookJwt(req, res) {
let { code } = req.params
logger.db('login', req)
if (!code) {
throw new ZError(10, 'params mismatch')
}
@ -38,6 +40,10 @@ class FacebookController extends BaseController {
user.scope = data['scopes']
if (infoRes['name']) user.nickname = infoRes['name']
if (infoRes['email']) user.email = infoRes['email']
const { api_platform } = req.headers
if (api_platform) {
user.platform = api_platform
}
let account = await Account.insertOrUpdate({ plat: PlatEnum.FACEBOOK, openId }, user)
const ztoken = await res.jwtSign({
id: account.id,

View File

@ -3,6 +3,7 @@ import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import { OAuth2Client } from 'google-auth-library'
import logger from 'logger/logger'
import { Account, PlatEnum } from 'modules/Account'
import { customAlphabet } from 'nanoid'
@ -16,6 +17,7 @@ class GoogleController extends BaseController {
@router('post /wallet/login/google')
async checkGoogleJwt(req, res) {
const { token } = req.params
logger.db('login', req)
const CLIENT_ID = process.env.GOOGLE_OAUTH_CLIENT
const CLIENT_ID2 = process.env.GOOGLE_OAUTH_CLIENT2
const CLIENT_ID_IOS = process.env.GOOGLE_OAUTH_CLIENT_IOS
@ -47,6 +49,10 @@ class GoogleController extends BaseController {
if (payload.locale) data.locale = payload.locale
if (payload.name) data.nickname = payload.name
if (payload.picture) data.avatar = payload.picture
const { api_platform } = req.headers
if (api_platform) {
data.platform = api_platform
}
let user = await Account.insertOrUpdate({ plat: PlatEnum.GOOGLE, openId }, data)
const ztoken = await res.jwtSign({
id: user.id,

View File

@ -22,6 +22,7 @@ class MailController extends BaseController {
@role(ROLE_ANON)
@router('post /wallet/login/email')
async loginWithEmail(req, res) {
logger.db('login', req)
let { email, password } = req.params
if (!email || !password) {
throw new ZError(10, 'params mismatch')
@ -52,6 +53,7 @@ class MailController extends BaseController {
@role(ROLE_ANON)
@router('post /email/regist')
async registMailAccount(req, res) {
logger.db('regist', req)
let { email, code, password } = req.params
if (!email || !code || !password) {
throw new ZError(10, 'params mismatch')
@ -74,6 +76,10 @@ class MailController extends BaseController {
account.updatePassword(password)
account.emailReal = email
account.emailVerified = true
const { api_platform } = req.headers
if (api_platform) {
account.platform = api_platform
}
await account.save()
record.status = CodeStatus.SUCCESS
await record.save()
@ -87,6 +93,7 @@ class MailController extends BaseController {
@role(ROLE_ANON)
@router('post /email/reset_password')
async resetMailPassword(req, res) {
logger.db('reset_pass', req)
let { email, code, password } = req.params
if (!email || !code || !password) {
throw new ZError(10, 'params mismatch')
@ -118,6 +125,7 @@ class MailController extends BaseController {
@role(ROLE_ANON)
@router('post /email/send_code')
async sendVerifyCode(req, res) {
logger.db('send_mail_code', req)
let { email, type } = req.params
if (!email || !type) {
throw new ZError(10, 'params mismatch')

View File

@ -1,18 +1,13 @@
import BaseController, { ROLE_ANON } from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import logger from 'logger/logger'
import { Account } from 'modules/Account'
class MainController extends BaseController {
@role(ROLE_ANON)
@router('post /client/login')
async clientLogin(req, res) {
const { code, token } = req.params
return {}
}
@router('post /wallet/account/reset')
async resetAccount(req, res) {
logger.db('reset_account', req)
let user = req.user
await user.updateOne({ $inc: { accountVersion: 1 } })
return {}

View File

@ -1,6 +1,7 @@
import BaseController from 'common/base.controller'
import { ZError } from 'common/ZError'
import { router } from 'decorators/router'
import logger from 'logger/logger'
import { TranRecord } from 'modules/TranRecord'
class RecordController extends BaseController {
@ -23,12 +24,13 @@ class RecordController extends BaseController {
let defaultParams: any = { account: user.id }
let { params } = req
Object.assign(params, defaultParams)
const records = await TranRecord.pageQuery(params, {json: 1})
const records = await TranRecord.pageQuery(params, { json: 1 })
return records
}
@router('delete /trans/record')
async delete(req) {
logger.db('delete_record', req)
let { ids } = req.params
const user = req.user
if (!ids) {

View File

@ -1,6 +1,7 @@
import BaseController, { ROLE_ANON } from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import logger from 'logger/logger'
import { Account, PlatEnum } from 'modules/Account'
import { fetchAccessToken, refreshAccessToken } from 'service/tiktok.svr'
// 在tiktok的过期时间中, 减少一个小时
@ -10,6 +11,7 @@ class TiktokController extends BaseController {
@router('post /wallet/login/tiktok')
async checkTiktokCode(req, res) {
let { code } = req.params
logger.db('login', req)
let result = await fetchAccessToken(code)
if (!(result.message === 'success' && result.data?.error_code === 0)) {
throw new ZError(10, `${result.message}: ${result.data?.description} (${result.data?.error_code})`)
@ -22,6 +24,10 @@ class TiktokController extends BaseController {
user.accessTokenExpire = now + result.data['expires_in'] - EXPIRE_REDUCE_SECOND
user.refreshTokenExpire = now + result.data['refresh_expires_in'] - EXPIRE_REDUCE_SECOND
user.scope = result.data['scope']
const { api_platform } = req.headers
if (api_platform) {
user.platform = api_platform
}
let account = await Account.insertOrUpdate({ plat: PlatEnum.TIKTOK, openId }, user)
const ztoken = await res.jwtSign({
id: account.id,

View File

@ -1,6 +1,7 @@
import BaseController, { ROLE_ANON } from 'common/base.controller'
import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router'
import logger from 'logger/logger'
import { Account } from 'modules/Account'
import { CodeRecord, CodeStatus, CodeType } from 'modules/CodeRecord'
import { DEFAULT_VERIFY_HTML, EmailSvr } from 'service/email.svr'
@ -17,6 +18,7 @@ class VerifyController extends BaseController {
*/
@router('post /email/verify')
async sendVerifyEmail(req, res) {
logger.db('verify_email', req)
let user = req.user
let { email } = req.params
if (!user.email && !email) {
@ -45,6 +47,7 @@ class VerifyController extends BaseController {
*/
@router('post /email/verify_by_code')
async verifyEmailByCode(req, res) {
logger.db('verify_by_code', req)
let user = req.user
let { email, code } = req.params
if (!email || !code) {

View File

@ -1,6 +1,7 @@
import BaseController from 'common/base.controller'
import { ZError } from 'common/ZError'
import { router } from 'decorators/router'
import logger from 'logger/logger'
import { Wallet } from 'modules/Wallet'
import { WalletBackup } from 'modules/WalletBackup'
@ -53,6 +54,7 @@ class WalletController extends BaseController {
@router('post /wallet/info')
async uploadWalletInfo(req, res) {
logger.db('update_wallet', req)
let user = req.user
let { address } = req.params
if (!address) {
@ -69,6 +71,7 @@ class WalletController extends BaseController {
@router('post /wallet/reset')
async resetWalletInfo(req, res) {
logger.db('reset_wallet', req)
let user = req.user
let record = await Wallet.findOne({ account: user.id })
if (!record) {

View File

@ -1,3 +1,9 @@
import { LoggerQueue } from 'queue/logger.queue'
const level = process.env.NODE_ENV === 'production' ? 'info' : 'log'
const logger = require('tracer').colorConsole({ dateformat: 'yyyy-mm-dd HH:MM:ss.L', level })
logger.db = function (name: string, req: any, logObj?: any) {
logObj = logObj || {}
new LoggerQueue().addLog(name, req, logObj)
}
export default logger

View File

@ -13,6 +13,7 @@ export enum PlatEnum {
TELEGRAM = 5,
EMAIL = 6,
DISCORD = 7,
CLIENT = 10,
}
/**
@ -106,6 +107,9 @@ class AccountClass extends BaseModule {
@prop({ default: 0 })
public accountVersion: number
@prop()
public platform: string
public static async findByEmail(this: ReturnModelType<typeof AccountClass>, email) {
return this.findOne({ email, plat: PlatEnum.EMAIL }).exec()
}

40
src/modules/UserLog.ts Normal file
View File

@ -0,0 +1,40 @@
import { dbconn } from '../decorators/dbconn'
import { getModelForClass, index, modelOptions, mongoose, prop, Ref } from '@typegoose/typegoose'
import { Severity } from '@typegoose/typegoose/lib/internal/constants'
import { BaseModule } from './Base'
/**
*
*/
@dbconn()
@index({ admin: 1 }, { unique: false })
@index({ name: 1 }, { unique: false })
@modelOptions({
schemaOptions: { collection: 'account_log', timestamps: true },
options: { allowMixed: Severity.ALLOW },
})
class UserLogClass extends BaseModule {
@prop()
public admin: string
@prop()
public name: string
@prop()
public method: string
@prop()
public path: string
@prop()
public referer: string
@prop()
public user_agent: string
@prop()
public platform: string
@prop()
public env: string
@prop()
public apiVersion: string
@prop()
public ip: string
@prop({ type: mongoose.Schema.Types.Mixed })
public params: any
}
export const UserLog = getModelForClass(UserLogClass, { existingConnection: UserLogClass['db'] })

44
src/queue/logger.queue.ts Normal file
View File

@ -0,0 +1,44 @@
import { AsyncQueue, createAsyncQueue } from 'common/AsyncQueue'
import { singleton } from 'decorators/singleton'
import logger from 'logger/logger'
import { UserLog } from 'modules/UserLog'
@singleton
export class LoggerQueue {
private queue: AsyncQueue
constructor() {
this.queue = createAsyncQueue()
}
public addLog(name, req, logObj) {
this.queue.push(async () => {
const user = req.user
const ip = req.headers['x-forwarded-for'] || req.ip
const { api_platform, api_version, api_env } = req.headers
const path = req.url
const params = req.method === 'GET' ? req.query : req.body
const dataObj = JSON.stringify(logObj) === '{}' ? params : logObj
try {
const history = new UserLog({
admin: user ? user.id : '',
username: user ? user.username : '',
path: path,
method: req.method,
params: dataObj,
referer: req.headers['referer'],
user_agent: req.headers['user-agent'],
ip,
apiVersion: api_version,
platform: api_platform,
env: api_env,
name,
})
await history.save()
} catch (err) {
logger.error('error add admin log: ')
logger.error(err)
}
})
}
}

View File

@ -120,6 +120,10 @@ export function compressUuid(e: string, t: boolean = false) {
return compressHex(e, r)
}
export function isUUID(uuid: string) {
return reNormalUUID.test(uuid)
}
const CHARS_BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
export function compressHex(e: string, r: number) {
var i,

725
yarn.lock

File diff suppressed because it is too large Load Diff