petcrypt-js-lite
Version:
Universal sdk for PET functionalities
183 lines • 7.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TEEClient = void 0;
const index_1 = require("../types/index");
const crypto_1 = require("../crypto");
const axios_1 = __importDefault(require("axios"));
const constants_1 = require("../constants");
const getWebSocket = () => {
if (typeof globalThis !== 'undefined' && 'WebSocket' in globalThis) {
return globalThis.WebSocket;
}
try {
const WebSocket = require('ws');
return WebSocket;
}
catch (error) {
throw new Error('No WebSocket implementation found. Install "ws" for Node.js support.');
}
};
class TEEClient {
constructor(config) {
this.config = config;
this.cipher = new crypto_1.Cipher();
this.WebSocket = getWebSocket();
this.teeGateway = new this.WebSocket(this.config.teeGatewayUrl);
}
async init() {
return new Promise((resolve, reject) => {
if (this.teeGateway.readyState === this.WebSocket.OPEN) {
resolve();
return;
}
if (this.teeGateway.readyState === this.WebSocket.CLOSED)
this.teeGateway = new this.WebSocket(this.config.teeGatewayUrl);
this.teeGateway.onopen = () => {
this.teeGateway.send(this.cipher.getPublicKey());
};
this.teeGateway.onmessage = (event) => {
let peerPublicKey = event.data;
if (peerPublicKey instanceof Blob) {
peerPublicKey.arrayBuffer().then((buffer) => {
this.cipher.deriveShareSecret(Buffer.from(buffer));
resolve();
});
}
else {
this.cipher.deriveShareSecret(peerPublicKey);
resolve();
}
};
this.teeGateway.onerror = (err) => {
reject(new Error(`WebSocket error: ${err}`));
};
this.teeGateway.onclose = () => {
reject(new Error('WebSocket closed unexpectedly'));
};
});
}
validateData(data, type) {
const throwError = (message) => {
throw new Error(message);
};
if (index_1.PlaintextType.isUint(type)) {
if (Number.isNaN(Number(data))) {
throwError('Invalid number');
}
if (Number(data) < 0)
throwError('Uint must be a positive number');
if (type === index_1.PlaintextType.uint8) {
if (Number(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint8])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint8]);
}
else if (type === index_1.PlaintextType.uint16) {
if (Number(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint16])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint16]);
}
else if (type === index_1.PlaintextType.uint32) {
if (Number(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint32])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint32]);
}
else if (type === index_1.PlaintextType.uint64) {
if (BigInt(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint64])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint64]);
}
else if (type === index_1.PlaintextType.uint128) {
if (BigInt(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint128])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint128]);
}
else if (type === index_1.PlaintextType.address) {
if (typeof data !== 'string')
throwError('Address must be a string');
else {
let length = data.startsWith('0x') ? data.length - 2 : data.length;
if (length !== 40)
throwError('Invalid address length');
return data.startsWith('0x') ?
Buffer.from(data.slice(2), 'hex') :
Buffer.from(data, 'hex');
}
}
else if (type === index_1.PlaintextType.uint256) {
if (BigInt(data) > index_1.TYPE_LIMIT[index_1.PlaintextType.uint256])
throwError(index_1.TYPE_LIMIT_MESSAGE[index_1.PlaintextType.uint256]);
}
return Buffer.from(data.toString());
}
else if (index_1.PlaintextType.isString(type)) {
if (typeof data !== 'string') {
throwError('String data type must be a string');
}
return Buffer.from(data, 'hex');
}
throwError('Unsupported data type');
}
async encrypt(data, type) {
await this.init();
const safeData = this.validateData(data, type);
if (!safeData)
return new Uint8Array();
const encryptedData = await this.cipher.aesEncrypt(safeData, type);
this.teeGateway.send(encryptedData);
return new Promise((resolve, reject) => {
const cleanup = () => {
this.teeGateway.onmessage = null;
this.teeGateway.onerror = null;
this.teeGateway.onclose = null;
};
this.teeGateway.onmessage = (event) => {
const handle = event.data;
if (handle instanceof Blob) {
handle.arrayBuffer().then((buffer) => {
cleanup();
resolve(new Uint8Array(buffer));
}).catch((err) => {
cleanup();
reject(new Error(`Error reading Blob data: ${err}`));
});
}
else {
cleanup();
resolve(new Uint8Array(handle));
}
};
this.teeGateway.onerror = (err) => {
cleanup();
reject(new Error(`WebSocket error: ${err}`));
};
this.teeGateway.onclose = () => {
cleanup();
reject(new Error('WebSocket closed unexpectedly'));
};
});
}
async decrypt(handle, chain) {
const DECRYPT_URL = constants_1.ENCRYPT_URL[chain].DECRYPT;
const payload = {
handle
};
let balance;
try {
const response = await axios_1.default.post(DECRYPT_URL, payload, {
headers: {
'Content-Type': 'application/json',
},
});
balance = response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
console.error('Error response:', error.response?.data);
}
else {
console.error('Unexpected error:', error);
}
}
return balance;
}
}
exports.TEEClient = TEEClient;
//# sourceMappingURL=TEEClient.js.map