UNPKG

@skalenetwork/bite

Version:

TS Library to interact with BITE protocol

1 lines 28.5 kB
{"version":3,"sources":["../src/core/encrypt.ts","../src/utils/logger.ts","../src/utils/constants.ts","../src/utils/helper.ts","../src/core/biteRpc.ts","../src/core/bite.ts"],"sourcesContent":["/**\n * @license\n * SKALE bite.ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file encrypt.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nimport {\n encryptMessage as encryptRawMessage,\n encryptMessageDualKey as encryptRawMessageDualKey,\n encryptMessageMockup as encryptRawMessageMockup\n} from '@skalenetwork/t-encrypt';\nimport { encode } from '@ethereumjs/rlp';\nimport {logger} from \"../utils/logger\";\nimport * as utils from '../utils/helper';\nimport * as constants from '../utils/constants';\n\n\nexport interface Transaction {\n to: string;\n data: string;\n gasLimit?: string;\n}\n\n/**\n * Encrypts a transaction using the real BLS key.\n *\n * @param {Transaction} tx - The transaction object.\n * @param {utils.CommitteeInfo[]} committees - The committees info object.\n * @param {string} [aadTE] - Optional TE Additional Authenticated Data.\n * @param {string} [aadAES] - Optional AES Additional Authenticated Data.\n * @returns {Promise<Transaction>} - A promise with encrypted transaction.\n *\n */\nexport async function encryptTransaction(\n tx: Transaction,\n committees: utils.CommitteeInfo[],\n aadTE?: string,\n aadAES?: string\n): Promise<Transaction> {\n try {\n const validatedTx = validateAndExtractTransactionFields(tx);\n const txTo = validatedTx.to;\n const txData = validatedTx.data;\n\n // RLP encode data and to fields\n const rlpEncodedData = rlpEncodeTransactionData(txTo, txData);\n\n const sanitizedAADAES = aadAES ? utils.remove0xPrefixIfNeeded(aadAES) : undefined;\n const sanitizedAADTE = aadTE ? utils.remove0xPrefixIfNeeded(aadTE) : undefined;\n\n if (sanitizedAADAES) utils.validateHexString(sanitizedAADAES);\n if (sanitizedAADTE) utils.validateHexString(sanitizedAADTE);\n\n const encryptedData = await encryptMessage(rlpEncodedData, committees, sanitizedAADTE, sanitizedAADAES);\n\n // Set default gasLimit if not set\n const biteGasLimit = tx.gasLimit ?? constants.DEFAULT_GAS_LIMIT;\n\n return {\n ...tx,\n data: encryptedData,\n to: constants.BITE_ADDRESS,\n gasLimit: biteGasLimit\n };\n } catch (error) {\n logger.error('Error encrypting transaction:', error);\n throw error;\n }\n}\n\n/**\n * Encrypts a transaction using mock encryption.\n *\n * @param {Transaction} tx - The transaction object.\n * @returns {Promise<Transaction>} - A promise with encrypted transaction.\n *\n */\nexport async function encryptTransactionMockup(tx: Transaction): Promise<Transaction> {\n try {\n const validatedTx = validateAndExtractTransactionFields(tx);\n const txTo = validatedTx.to;\n const txData = validatedTx.data;\n\n // RLP encode data and to fields\n const rlpEncodedData = rlpEncodeTransactionData(txTo, txData);\n\n const encryptedData = await encryptMessageMockup(rlpEncodedData);\n \n // Set default gasLimit if not set\n const biteGasLimit = tx.gasLimit ?? constants.DEFAULT_GAS_LIMIT;\n \n return {\n ...tx,\n data: encryptedData,\n to: constants.BITE_ADDRESS,\n gasLimit: biteGasLimit\n };\n } catch (error) {\n logger.error('Error encrypting transaction (mockup):', error);\n throw error;\n }\n}\n\n/**\n * Encrypts a raw hex-encoded message using the real BLS key(s).\n *\n * @param {string} message - The message to encrypt, as a hex string (with or without 0x prefix).\n * @param {utils.CommitteeInfo[]} committees - The committees info object.\n * @param {string} [aadTE] - Optional TE Additional Authenticated Data, as a hex string.\n * @param {string} [aadAES] - Optional AES Additional Authenticated Data, as a hex string.\n * @returns {Promise<string>} - The encrypted message.\n */\nexport async function encryptMessage(\n message: string,\n committees: utils.CommitteeInfo[],\n aadTE?: string,\n aadAES?: string\n): Promise<string> {\n try {\n const data = utils.remove0xPrefixIfNeeded(message);\n utils.validateHexString(data);\n\n const sanitizedAADTE = aadTE ? utils.remove0xPrefixIfNeeded(aadTE) : undefined;\n const sanitizedAADAES = aadAES ? utils.remove0xPrefixIfNeeded(aadAES) : undefined;\n \n if (sanitizedAADAES) {\n utils.validateHexString(sanitizedAADAES);\n }\n if (sanitizedAADTE) {\n utils.validateHexString(sanitizedAADTE);\n }\n\n if (committees.length === 1) {\n const publicKeyResponse = committees[0];\n const encryptedRawMessage = await encryptRawMessage(data, publicKeyResponse.commonBLSPublicKey, sanitizedAADTE, sanitizedAADAES);\n\n // RLP encode epochID and encrypted message\n const rlpEncodedResult = rlpEncodeMessageData([publicKeyResponse.epochId, Buffer.from(encryptedRawMessage, 'hex')]);\n return `0x${rlpEncodedResult}`;\n } else {\n const encryptedRawMessage = await encryptRawMessageDualKey(data, committees[0].commonBLSPublicKey,\n committees[1].commonBLSPublicKey, sanitizedAADTE, sanitizedAADAES);\n\n // RLP encode epochID and encrypted message\n const rlpEncodedResult = rlpEncodeMessageData([committees[0].epochId, Buffer.from(encryptedRawMessage, 'hex')]);\n return `0x${rlpEncodedResult}`;\n }\n } catch (error) {\n logger.error('Error encrypting message:', error);\n throw error;\n }\n}\n\n/**\n * Encrypts a raw hex-encoded message using mock encryption.\n *\n * @param {string} message - The message to encrypt, as a hex string (with or without 0x prefix).\n * @returns {Promise<string>} - The encrypted message.\n */\nexport async function encryptMessageMockup(\n message: string\n): Promise<string> {\n try {\n const data = utils.remove0xPrefixIfNeeded(message);\n\n if (!/^[0-9a-fA-F]*$/.test(data) || data.length % 2 !== 0) {\n throw new Error(\"Invalid input: message must be valid hex and even length\");\n }\n\n const encryptedRawMessage = await encryptRawMessageMockup(data);\n const epochId = 0;\n\n // RLP encode epochID and encrypted message\n const rlpEncodedResult = rlpEncodeMessageData([epochId, Buffer.from(encryptedRawMessage, 'hex')]);\n return `0x${rlpEncodedResult}`;\n } catch (error) {\n logger.error('Error encrypting message:', error);\n throw error;\n }\n}\n\n/**\n * Validates a transaction object for encryption and extracts the fields to be encrypted.\n * @param {object} tx - The transaction object containing a 'data' and 'to' fields (hex string).\n * @returns {{ data: string, to: string}} An object with the 'data' and 'to' fields properly validated\n * and formatted as hexadecimal strings without the '0x' prefix.\n */\nfunction validateAndExtractTransactionFields(tx: Transaction): Transaction {\n const isValid = tx && typeof tx === 'object' && \n tx.data && tx.to && \n typeof tx.data === 'string' && \n typeof tx.to === 'string';\n \n if (!isValid) {\n throw new Error(\"Invalid input: Must be an object with 'data' and 'to' fields of type string\");\n }\n\n const txData = utils.remove0xPrefixIfNeeded(tx.data);\n const txTo = utils.remove0xPrefixIfNeeded(tx.to);\n\n // Validate that the data and to fields contain only hex characters and are of even length\n utils.validateHexString(txData);\n utils.validateHexString(txTo);\n\n if (txTo.length !== 40) {\n throw new Error(\"Invalid input: 'to' field must be exactly 20 bytes (40 hex characters) long\");\n }\n\n return { data: txData, to: txTo };\n}\n\n/**\n * RLP encodes transaction data and to address\n * @param {string} txTo - The transaction to address as hex string (without 0x prefix)\n * @param {string} txData - The transaction data as hex string (without 0x prefix)\n * @returns {string} RLP encoded data as hex string (without 0x prefix)\n */\nfunction rlpEncodeTransactionData(txTo: string, txData: string): string {\n try {\n // Convert hex strings to Buffer for RLP encoding\n const toBuffer = Buffer.from(txTo, 'hex');\n const dataBuffer = Buffer.from(txData, 'hex');\n \n // RLP encode as array [txData, txTo]\n const rlpEncoded = encode([dataBuffer, toBuffer]);\n \n // Convert back to hex string without 0x prefix\n return Buffer.from(rlpEncoded).toString('hex');\n } catch (error) {\n logger.error('Error RLP encoding transaction data:', error);\n throw new Error('Failed to RLP encode transaction data');\n }\n}\n\n/**\n * RLP encodes array of epochId and encrypted message\n * @param {(number | Buffer | (number | Buffer)[])[]} data - Array of data to RLP encode\n * @returns {string} RLP encoded data as hex string (without 0x prefix)\n */\nfunction rlpEncodeMessageData(data: (number | Buffer | (number | Buffer)[])[]): string {\n try {\n // RLP encode the array\n const rlpEncoded = encode(data);\n \n // Convert back to hex string without 0x prefix\n return Buffer.from(rlpEncoded).toString('hex');\n } catch (error) {\n logger.error('Error RLP encoding message data:', error);\n throw new Error('Failed to RLP encode message data');\n }\n}","/**\n * @license\n * SKALE bite.ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file logger.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nimport { Logger, type ILogObj } from 'tslog';\nimport { NODE_ENV } from './constants';\n\nconst isDev = NODE_ENV === 'development';\n\nconst logger = new Logger<ILogObj>({\n name: 'bite',\n minLevel: isDev ? 'info' : 9,\n});\n\nexport { logger };\n","/**\n * @license\n * SKALE bite.ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file constants.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nexport const BITE_ADDRESS = '0x42495445204D452049274d20454e435259505444';\nexport const DEFAULT_GAS_LIMIT = '0x493e0'; // 300000\nexport const NODE_ENV = process.env.NODE_ENV","/**\n * @license\n * SKALE libte-ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file helper.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nexport interface CommitteeInfo {\n commonBLSPublicKey: string;\n epochId: number;\n}\n\nexport function remove0xPrefixIfNeeded(str: string): string {\n return str.startsWith('0x') ? str.slice(2) : str;\n}\n\nexport function validateUrl(url: string): void {\n try {\n new URL(url);\n } catch {\n throw new Error(`Invalid provider URL: ${url}`);\n }\n}\n\nexport function validateHexString(str: string): void {\n if (!/^[0-9a-fA-F]*$/.test(str)) {\n throw new Error(\"Invalid input: Must contain only hexadecimal characters\");\n }\n if (str.length % 2 !== 0) {\n throw new Error(\"Invalid input: Must have an even length\");\n }\n}","/**\n * @license\n * SKALE libte-ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file biteRpc.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nimport * as utils from '../utils/helper';\nimport {logger} from \"../utils/logger\";\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n method: string;\n params: unknown[];\n id: number;\n}\n\ninterface JsonRpcSuccess<T> {\n jsonrpc: '2.0';\n result: T;\n id: number;\n}\n\ninterface JsonRpcError<E> {\n jsonrpc: '2.0';\n error: {\n code: number;\n message: string;\n data?: E;\n };\n id: number;\n}\n\ntype JsonRpcResponse<T = unknown, E = unknown> = JsonRpcSuccess<T> | JsonRpcError<E>;\n\n/**\n * Fetch decrypted transaction data via JSON-RPC endpoint.\n *\n * @param endpoint - BITE URL provider.\n * @param transactionHash - The hash of the transaction to decrypt.\n * @returns The decrypted transaction data.\n */\nexport async function getDecryptedTransactionData(\n endpoint: string,\n transactionHash: string\n): Promise<string> {\n try {\n utils.validateUrl(endpoint);\n\n const requestBody: JsonRpcRequest = {\n jsonrpc: '2.0',\n method: 'bite_getDecryptedTransactionData',\n params: [transactionHash],\n id: 1,\n };\n\n const result = await sendRpcRequest<string>(endpoint, requestBody);\n\n return result;\n } catch (error) {\n logger.error('Error fetching decrypted transaction data:', error);\n throw error;\n }\n}\n\n/**\n * Requests the committees info via JSON-RPC.\n *\n * @param endpoint - BITE URL provider.\n * @returns An array of objects containing the BLS public key and epoch ID.\n * @throws If the response is invalid or the key format is incorrect.\n */\nexport async function getCommitteesInfo(endpoint: string): Promise<utils.CommitteeInfo[]> {\n try {\n const requestBody: JsonRpcRequest = {\n jsonrpc: '2.0',\n method: 'bite_getCommitteesInfo',\n params: [],\n id: 1,\n };\n \n const result = await sendRpcRequest<utils.CommitteeInfo[]>(endpoint, requestBody);\n\n if (!Array.isArray(result)) {\n throw new Error('Result is not an array');\n }\n\n if (result.length === 0 || result.length > 2) {\n throw new Error(`Expected array of size 1 or 2, got ${result.length}`);\n }\n\n // Validate each element in the array\n for (const item of result) {\n if (typeof item !== 'object' || item === null) {\n throw new Error('Array element is not an object');\n }\n\n if (typeof item.commonBLSPublicKey !== 'string') {\n throw new Error('commonBLSPublicKey is not a string');\n }\n\n if (typeof item.epochId !== 'number') {\n throw new Error('epochId is not a number');\n }\n\n if (!/^[0-9a-fA-F]{256}$/.test(item.commonBLSPublicKey)) {\n throw new Error('commonBLSPublicKey is not a valid 256-character hexadecimal string');\n }\n }\n\n return result;\n } catch (error) {\n logger.error('Error fetching BITE common public key:', error);\n throw error;\n }\n}\n\nasync function sendRpcRequest<ResponseType>(endpoint: string, requestBody: JsonRpcRequest): Promise<ResponseType> {\n try {\n utils.validateUrl(endpoint);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(requestBody),\n });\n\n if (response.status !== 200) {\n throw new Error(`Received status code: ${response.status}`);\n }\n\n const data = await response.json() as JsonRpcResponse<ResponseType>;\n\n if ('error' in data) {\n throw new Error(`Error from server: ${data.error.message}`);\n }\n\n return data.result;\n } catch (error) {\n logger.error('Error sending RPC request:', error);\n throw error;\n }\n}\n","/**\n * @license\n * SKALE libte-ts\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * @file bite.ts\n * @copyright SKALE Labs 2025-Present\n */\n\nimport * as encrypt from './encrypt';\nimport * as biteRpc from './biteRpc';\nimport * as utils from '../utils/helper';\n\nexport class BITE {\n private readonly providerURL: string;\n\n constructor(providerURL: string) {\n this.providerURL = providerURL;\n }\n\n /**\n * Encrypt a hex-encoded message using BLS public key.\n * @param message - Hex string (with or without 0x).\n */\n async encryptMessage(message: string): Promise<string> {\n const committees = await biteRpc.getCommitteesInfo(this.providerURL);\n return encrypt.encryptMessage(message, committees);\n }\n\n /**\n * Encrypt a transaction object using BLS public key.\n * @param tx - The transaction to encrypt.\n */\n async encryptTransaction(tx: encrypt.Transaction): Promise<encrypt.Transaction> {\n const committees = await biteRpc.getCommitteesInfo(this.providerURL);\n return encrypt.encryptTransaction(tx, committees);\n }\n\n /**\n * Encrypt a hex-encoded message using BLS public key for CTX.\n * @param message - Hex string (with or without 0x).\n * @param ctxSubmitterAddress - Smart Contract Address for aadTE.\n */\n async encryptMessageForCTX(message: string, ctxSubmitterAddress: string): Promise<string> {\n const committees = await biteRpc.getCommitteesInfo(this.providerURL);\n return encrypt.encryptMessage(message, committees, ctxSubmitterAddress);\n }\n\n /**\n * Encrypt a transaction object using BLS public key and provided committees info.\n * @param tx - The transaction to encrypt.\n * @param committees - The committees info object.\n */\n static async encryptTransactionWithCommitteeInfo(\n tx: encrypt.Transaction,\n committees: utils.CommitteeInfo[]\n ): Promise<encrypt.Transaction> {\n return encrypt.encryptTransaction(tx, committees);\n }\n\n /**\n * Fetch the committees info from the configured endpoint.\n */\n async getCommitteesInfo(): Promise<utils.CommitteeInfo[]> {\n return biteRpc.getCommitteesInfo(this.providerURL);\n }\n\n /**\n * Get decrypted transaction data using the configured endpoint.\n * @param transactionHash - The hash of the transaction.\n */\n async getDecryptedTransactionData(transactionHash: string): Promise<string> {\n return biteRpc.getDecryptedTransactionData(this.providerURL, transactionHash);\n }\n}\n\n\nexport class BITEMockup {\n /**\n * Simulates encryption of a hex-encoded message\n *\n * @param message - Hex string (with or without 0x).\n */\n async encryptMessage(message: string): Promise<string> {\n return encrypt.encryptMessageMockup(message);\n }\n\n /**\n * Simulates encryption of a transaction object\n *\n * @param tx - The transaction to encrypt.\n */\n async encryptTransaction(tx: encrypt.Transaction): Promise<encrypt.Transaction> {\n return encrypt.encryptTransactionMockup(tx);\n }\n}"],"mappings":"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","names":[]}