UNPKG

kalp-pkg

Version:

KALP blockchain SDK for cryptographic operations and blockchain interactions

827 lines (823 loc) 32.9 kB
import { Wallet, Mnemonic } from 'ethers'; import elliptic from 'elliptic'; import { KEYUTIL, KJUR } from 'jsrsasign'; import CryptoJS from 'crypto-js'; import fetch from 'cross-fetch'; import { webcrypto } from 'crypto'; //Common key const value const P256_SIGN_CURVE = 'p256'; const SECP256R1_SIGN_CURVE = 'secp256r1'; const EXPORT_PUBLIC_KEY_FORMAT = 'spki'; const KEY_PAIR_FORMAT_TYPE = 'hex'; const EXPORT_PRIVATE_KEY_FORMAT = 'pkcs8'; const PRIVATE_KEY_TYPE = 'PKCS8PRV'; const SPECIAL_CHARACTERS = '!@#$%^&*+-='; const UPPER_CASE_CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const LOWER_CASE_CHARACTERS = 'abcdefghijklmnopqrstuvwxyz'; const NUMBERS = '0123456789'; //For registration and certificates const AUTHORIZATION_KEY = 'f5b1aca0717e01d0dbca408d281e9e5145250acb146ff9f0844d53e95aab30b5'; const CONTENT_TYPE = 'application/json'; const MAX_ENROLLMENTS = '-1'; const URL_CHANNEL_NAME = 'kalpstagenet'; const URL_CHANNEL_NAME_TESTNET = 'prod-test-mainnet'; const URL_CHANNEL_NAME_INTMAINNET = 'intmainnet-mailabs'; const NETWORK_GOVERNANCE_BASE_URL = 'https://dev-userreg-gov.p2eppl.com/v1'; const NETWORK_GOVERNANCE_STG_BASE_URL = 'https://stg-userreg-gov.p2eppl.com/v1'; const NETWORK_GOVERNANCE_TESTNET_BASE_URL = 'https://ngl-userreg-test.kalp.network/v1'; const REGISTER_URL = '/pki/register'; const ENROLL_CSR_URL = '/pki/enrollCsr'; const BASE_64_TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // Read and write function const SIGN = 'sign'; const KEY_FORMAT = 'raw'; const SIGN_ALGORITHM = 'ECDSA'; const NAMED_CURVE = 'P-256'; const VERIFY_OPERATION = 'verify'; const HASH_ALGORITHM = 'SHA-256'; const SIGNATURE_ALGORITHM = 'SHA256withECDSA'; const BEGIN_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----'; const END_PRIVATE_KEY = '-----END PRIVATE KEY-----'; const KALP_GATEWAY_BASE_URL = 'https://stg-kalp-gateway.p2eppl.com/transaction/v1'; const KALP_GATEWAY_INTMAINNET_BASE_URL = 'https://intmainnet-kalp-gateway.p2eppl.com/transaction/v1'; const KALP_GATEWAY_TESTNET_BASE_URL = 'https://rpc-mumbai-test.kalp.network/transaction/v1'; const ENCRYPTION_KEY = 'asdfghjklqwyuiopzxcvbnm1234567890123456'; // Must be 32 characters for AES-256 // @ts-nocheck //import { ethers } from 'ethers'; const EC = elliptic.ec; // Cross-platform crypto support let crypto; if (typeof window !== 'undefined' && window.crypto) { crypto = window.crypto; } else if (typeof global !== 'undefined') { // Node.js environment crypto = webcrypto; } else { throw new Error('Crypto API not available in this environment'); } /** * Environment variable for the network you need to connect . */ const Network = { Stagenet: 'STAGENET', Testnet: 'TESTNET', Mainnet: 'MAINNET', IntegrationMainnet: 'INTEGRATIONMAINNET', }; /** * getSeedPhrase */ async function getSeedPhrase() { try { const wallet = Wallet.createRandom(); return wallet.mnemonic.phrase; } catch (error) { throw new Error('An error occurred while getting seed phrase: ' + error.message); } } /** * getKeyPairFromSeedPhrase * @param {string} seedPhrase - Need to give seedphrase. */ async function getKeyPairFromSeedPhrase(seedPhrase) { try { const ec = new EC(P256_SIGN_CURVE); const mnemonic = Mnemonic.fromPhrase(seedPhrase); const seed = await mnemonic.computeSeed(); // Generate ECDSA key pair const key = ec.keyFromPrivate(seed); const privateKey = key.getPrivate(KEY_PAIR_FORMAT_TYPE); const publicKey = key.getPublic(KEY_PAIR_FORMAT_TYPE); // Parse the hex private key const convPrivateKey = KEYUTIL.getKey({ curve: SECP256R1_SIGN_CURVE, d: privateKey, }); const pemPrivateKey = KEYUTIL.getPEM(convPrivateKey, PRIVATE_KEY_TYPE); const pemPublicKey = await convertPublicKeyHexToPem(publicKey); return { pemPrivateKey, pemPublicKey }; } catch (error) { throw Error('An error occurred while getting keypair:' + error); } } //convertPublicKeyHexToPem async function convertPublicKeyHexToPem(pubKey) { try { const publicKeyBuffer = new Uint8Array(pubKey.length / 2); for (let i = 0; i < pubKey.length; i += 2) { publicKeyBuffer[i / 2] = parseInt(pubKey.substr(i, 2), 16); } const publicKey = await crypto.subtle.importKey(KEY_FORMAT, publicKeyBuffer, { name: SIGN_ALGORITHM, namedCurve: NAMED_CURVE, }, true, [VERIFY_OPERATION]); const publicKeyPem = await extractPublicKey(publicKey); return publicKeyPem; } catch (error) { throw new Error('An error occurred while converting public key hex format to pem' + error); } } //extractPublicKey async function extractPublicKey(publicKey) { try { const exportedKey = await crypto.subtle.exportKey(EXPORT_PUBLIC_KEY_FORMAT, publicKey); // Use SPKI format const pemKey = await formatPublicKeyToPem(exportedKey); // Convert to PEM string return pemKey; } catch (error) { throw new Error('An error occurred while converting publicKey from cryptoKey format to pem: ' + error); } } //formatPublicKeyToPem async function formatPublicKeyToPem(publicKey) { try { const publicKeyData = String.fromCharCode.apply(null, Array.from(new Uint8Array(publicKey))); const base64Key = btoa(publicKeyData); const pemKey = `-----BEGIN PUBLIC KEY-----\n${base64Key}\n-----END PUBLIC KEY-----\n`; return pemKey; } catch (error) { throw new Error('An error occurred while formatting base64key to pem key' + error); } } /** * getKeyPair */ async function getKeyPair() { try { const keyPair = await generateKeyPairUsingCryptoSubtle(); const privateKeyCrypto = keyPair.privateKey; const publicKeyCrypto = keyPair.publicKey; const pemPublicKey = await extractPublicKey(publicKeyCrypto); const pemPrivateKey = await exportPrivateKeyAsPem(privateKeyCrypto); return { pemPrivateKey, pemPublicKey }; } catch (error) { throw new Error('An error occurred while getting public and private key pair:' + error); } } //generateKeyPairUsingCryptoSubtle async function generateKeyPairUsingCryptoSubtle() { try { const keyPair = await crypto.subtle.generateKey({ name: SIGN_ALGORITHM, namedCurve: NAMED_CURVE, // or "P-384" or "P-521" }, true, [SIGN, VERIFY_OPERATION]); return keyPair; } catch (error) { throw new Error('An error occurred while generating key pair from generateKeyPairUsingCryptoSubtle function' + error); } } /** * getEnrollmentId * @param {string} publicKey - Provide PEM format public key. */ async function getEnrollmentId(publicKey) { try { const regex = /-----BEGIN PUBLIC KEY-----\r?\n|\r?\n?-----END PUBLIC KEY-----\r?\n?|\r?\n/g; const pemPublicKeyString = publicKey.replace(regex, ''); const pemPublicKeyBytes = await decodeBase64String(pemPublicKeyString); const hashedPemPublicKey = await hashByteArray(pemPublicKeyBytes); const initialEnrollmentId = await convertByteArrayToString(hashedPemPublicKey); const enrollmentID = initialEnrollmentId.slice(-40); return enrollmentID; } catch (error) { throw new Error('An error occurred while getting enrollmentId : ' + error); } } //hashByteArray async function hashByteArray(uint8Array) { try { const buffer = uint8Array.buffer.slice(uint8Array.byteOffset, uint8Array.byteOffset + uint8Array.byteLength); const hashBuffer = await crypto.subtle.digest(HASH_ALGORITHM, buffer); const hashUint8Array = new Uint8Array(hashBuffer); return hashUint8Array; } catch (error) { throw new Error('An error occurred while getting hashByteArray' + error); } } //convertByteArrayToString async function convertByteArrayToString(src) { try { const dst = new Uint8Array(src.length * 2); // Each byte will be represented by 2 characters in hexadecimal for (let i = 0; i < src.length; i++) { const byte = src[i]; dst[i * 2] = (byte >> 4) & 0xf; // High nibble dst[i * 2 + 1] = byte & 0xf; // Low nibble } return Array.from(dst) .map((byte) => byte.toString(16)) .join(''); } catch (error) { throw new Error('An error occurred in convertByteArrayToString function' + error); } } /** * createCsr * @param {string} enrollmentID - provide enrollment id in string. * @param {string} privateKeyPem - Provide PEM format private key. * @param {string} publicKey - Provide PEM format public key. */ function createCsr(enrollmentID, privateKeyPem, publicKeyPem) { try { const csr = new KJUR.asn1.csr.CertificationRequest({ subject: { str: `/CN=${enrollmentID}/O=Your Organization/postalCode=Your Postal Code/L=Your Locality/ST=Your Province/C=IN`, }, sbjpubkey: publicKeyPem, sigalg: SIGNATURE_ALGORITHM, sbjprvkey: privateKeyPem, }); const pem = csr.getPEM(); return pem; } catch (error) { throw new Error('An error occurred while Creating CSR :' + error); } } /** * GetNetworkGovernanceUrl - Outputs the base url of network governance layer * @param {string} environment - provide environment detail in string format. */ function GetNetworkGovernanceUrl(environment) { switch (environment) { case Network.Stagenet: return NETWORK_GOVERNANCE_BASE_URL; case Network.IntegrationMainnet: return NETWORK_GOVERNANCE_STG_BASE_URL; case Network.Testnet: return NETWORK_GOVERNANCE_TESTNET_BASE_URL; default: throw new Error('An error occurred while getting network governance url :' + 'invalid environment variable passed'); } } /** * GetKalpGatewayUrl - Outputs the base url of kalp gateway * @param {string} environment - provide environment detail in string format. */ function GetKalpGatewayUrl(environment) { switch (environment) { case Network.Stagenet: return KALP_GATEWAY_BASE_URL; case Network.IntegrationMainnet: return KALP_GATEWAY_INTMAINNET_BASE_URL; case Network.Testnet: return KALP_GATEWAY_TESTNET_BASE_URL; default: throw new Error('An error occurred while getting kalp gateway url :' + 'invalid environment variable passed'); } } /** * registerAndEnrollUser * @param {string} network - provide network to which you want to register to. * @param {string} enrollmentID - provide enrollment id in string. * @param {string} csr - Provide certificate. */ async function registerAndEnrollUser(network, nglURL, channelName, enrollmentID, csr) { try { if (enrollmentID.length !== 40) { throw new Error('Invalid enrollment ID: Must be 40 characters long.'); } const encryptedWord = await getSecret(enrollmentID); const networkGovernanceBaseUrl = nglURL || GetNetworkGovernanceUrl(network); const endpoint = networkGovernanceBaseUrl + REGISTER_URL; const headers = { Authorization: AUTHORIZATION_KEY, 'Content-Type': CONTENT_TYPE, }; const body = { enrollmentid: enrollmentID, secret: encryptedWord, maxenrollments: MAX_ENROLLMENTS, channel: channelName || getNGChannelName(network), }; const response = await fetch(endpoint, { method: 'POST', headers: headers, body: JSON.stringify(body), }); if (!response.ok) { const jsonData = await response.json(); const finalResponse = JSON.stringify(jsonData); throw new Error('An error occurred while doing user registration' + finalResponse); } else { const endpoint = networkGovernanceBaseUrl + ENROLL_CSR_URL; const headers = { Authorization: AUTHORIZATION_KEY, 'Content-Type': CONTENT_TYPE, }; const body = { enrollmentid: enrollmentID, secret: encryptedWord, csr: csr, channel: channelName || getNGChannelName(network), }; const response = await fetch(endpoint, { method: 'POST', headers: headers, body: JSON.stringify(body), }); if (!response.ok) { const jsonData = await response.json(); const finalResponse = JSON.stringify(jsonData); throw new Error('An error occurred while getting certificate' + finalResponse); } else { const responseData = await response.json(); const cert = responseData.response.pubcert; return cert; } } } catch (error) { throw new Error('An error occurred in user registration process ' + error); } } /** * register * @param {string} network - provide network to which you want to register to. * @param {string} enrollmentID - provide enrollment id in string format. * @param {string} encryptedWord - provide secret in string format. */ async function register(network, nglURL, channelName, enrollmentID, encryptedWord) { try { if (enrollmentID.length !== 40) { throw new Error('Invalid enrollment ID: Must be 40 characters long.'); } const networkGovernanceBaseUrl = nglURL || GetNetworkGovernanceUrl(network); const endpoint = networkGovernanceBaseUrl + REGISTER_URL; const headers = { Authorization: AUTHORIZATION_KEY, 'Content-Type': CONTENT_TYPE, }; const body = { enrollmentid: enrollmentID, secret: encryptedWord, maxenrollments: MAX_ENROLLMENTS, channel: channelName || getNGChannelName(network), }; const response = await fetch(endpoint, { method: 'POST', headers: headers, body: JSON.stringify(body), }); if (!response.ok) { const jsonData = await response.json(); const finalResponse = JSON.stringify(jsonData); throw new Error('An error occurred while doing user registration' + finalResponse); } const jsonData = await response.json(); const responseData = JSON.stringify(jsonData); return responseData; } catch (error) { throw new Error('An error occurred while doing user registration' + error); } } /** * enrollCsr * @param {string} network - provide network to which you want to register to. * @param {string} enrollmentID - provide enrollment id in string format. * @param {string} encryptedWord - provide secret in string format. * @param {string} csr - Provide certificate. */ async function enrollCsr(network, nglURL, channelName, enrollmentID, encryptedWord, csr) { try { const networkGovernanceBaseUrl = nglURL || GetNetworkGovernanceUrl(network); const endpoint = networkGovernanceBaseUrl + ENROLL_CSR_URL; const headers = { Authorization: AUTHORIZATION_KEY, 'Content-Type': CONTENT_TYPE, }; const body = { enrollmentid: enrollmentID, secret: encryptedWord, csr: csr, channel: channelName || getNGChannelName(network), }; const response = await fetch(endpoint, { method: 'POST', headers: headers, body: JSON.stringify(body), }); if (!response.ok) { const jsonData = await response.json(); const finalResponse = JSON.stringify(jsonData); throw new Error('An error occurred while getting certificate' + finalResponse); } else { const responseData = await response.json(); const cert = responseData.response.pubcert; return cert; } } catch (error) { throw new Error('An error occurred while getting certificate' + error); } } /** * getSecret * @param {string} enrollmentID - provide enrollment id in string format. */ async function getSecret(enrollmentID) { try { function bufferToHex(buffer) { return Array.from(new Uint8Array(buffer)) .map((b) => b.toString(16).padStart(2, '0')) .join(''); } // Encode the input string as a Uint8Array const encoder = new TextEncoder(); const data = encoder.encode(enrollmentID); // Hash the input using SHA-256 const hashBuffer = await crypto.subtle.digest('SHA-256', data); const hash = bufferToHex(hashBuffer); // Define character sets const upperCaseLetters = UPPER_CASE_CHARACTERS; const lowerCaseLetters = LOWER_CASE_CHARACTERS; const specialCharacters = SPECIAL_CHARACTERS; const numbers = NUMBERS; // Combine all characters into one string const allCharacters = upperCaseLetters + lowerCaseLetters + specialCharacters + numbers; // Function to get a character from allCharacters based on hash value function getCharFromHash(hash, index) { const charIndex = parseInt(hash.slice(index * 2, index * 2 + 2), 16) % allCharacters.length; return allCharacters[charIndex]; } // Ensure at least one character from each set is included let uniqueString = ''; uniqueString += upperCaseLetters[parseInt(hash.slice(0, 2), 16) % upperCaseLetters.length]; uniqueString += lowerCaseLetters[parseInt(hash.slice(2, 4), 16) % lowerCaseLetters.length]; uniqueString += specialCharacters[parseInt(hash.slice(4, 6), 16) % specialCharacters.length]; uniqueString += numbers[parseInt(hash.slice(6, 8), 16) % numbers.length]; // Fill the rest of the string with characters from the hash for (let i = 4; i < 16; i++) { uniqueString += getCharFromHash(hash, i); } return uniqueString; } catch (error) { throw new Error('An error occurred while getting secret from enrollment ID ' + error); } } /** * submitTransaction * @param {string} network - provide network to which you want to submit transaction. * @param {string} enrollmentID - provide enrollment id in string. * @param {string} pemPrivateKey - Provide PEM format private key. * @param {string} cert - Provide certificate. * @param {string} channelName - provide channelName in string. * @param {string} chainCodeName - provide chainCodeName in string. * @param {string} transactionName - provide transactionName in string. * @param {Array} transactionParams - Provide transactionParams in an array. */ async function submitTransaction(network, gatewayURL, enrollmentID, pemPrivateKey, cert, channelName, chainCodeName, transactionName, transactionParams) { try { const domainName = gatewayURL || GetKalpGatewayUrl(network); const proposalUrl = domainName + '/proposal'; const endorsementUrl = domainName + '/endorse'; const submitUrl = domainName + '/submit'; const commitSubmitUrl = domainName + '/commitstatus'; const privateKeyString = pemPrivateKey; //try change name from privatekey to pemPrivate key const transaction = { enrollmentID: enrollmentID, cert: cert, channelName: channelName, chainCodeName: chainCodeName, transactionName: transactionName, transactionParams: transactionParams, }; //proposal const proposalData = await restCall(proposalUrl, transaction); let sigr = ''; let sigs = ''; const proposal = proposalData.message.proposal; const proposalBytes = await decodeBase64String(proposal); [sigr, sigs] = await signUsingElliptic(privateKeyString, proposalBytes); const signedProposal = { signedR: sigr, signedS: sigs, proposal: proposal, }; //endorse const endorseData = await restCall(endorsementUrl, signedProposal); const endorse = endorseData.message.endorse; const endorsedProposalBytes = await decodeBase64String(endorse); [sigr, sigs] = await signUsingElliptic(privateKeyString, endorsedProposalBytes); const signedEndorsedProposal = { signedR: sigr, signedS: sigs, endorse: endorse, }; //submit const submitData = await restCall(submitUrl, signedEndorsedProposal); const submit = submitData.message.submit; const submitProposalBytes = await decodeBase64String(submit); [sigr, sigs] = await signUsingElliptic(privateKeyString, submitProposalBytes); const signedCommitProposal = { signedR: sigr, signedS: sigs, submit: submit, }; //commitstatus const statusData = await restCall(commitSubmitUrl, signedCommitProposal); function getTransactionId(statusData) { return statusData.message.transaction_id; } const transactionId = getTransactionId(statusData); return transactionId; } catch (error) { throw new Error('An error occurred while submiting transaction ' + error); } } /** * evaluateTransaction * @param {string} network - provide network to which you want to evaluate transaction. * @param {string} enrollmentID - provide enrollment id in string. * @param {string} privateKeyString - Provide PEM format private key. * @param {string} cert - Provide certificate. * @param {string} channelName - provide channelName in string. * @param {string} chainCodeName - provide chainCodeName in string. * @param {string} transactionName - provide transactionName in string. * @param {Array} transactionParams - Provide transactionParams in an array. */ async function evaluateTransaction(network, gatewayURL, enrollmentID, privateKeyString, cert, channelName, chainCodeName, transactionName, transactionParams) { try { const domainName = gatewayURL || GetKalpGatewayUrl(network); const proposalUrl = domainName + '/proposal'; const evaluateUrl = domainName + '/evaluate'; const transaction = { enrollmentID: enrollmentID, cert: cert, channelName: channelName, chainCodeName: chainCodeName, transactionName: transactionName, transactionParams: transactionParams, }; const evaluateTransactionValue = await evaluateSignedTransaction(privateKeyString, proposalUrl, evaluateUrl, transaction); return evaluateTransactionValue; } catch (error) { throw new Error('An error occurred while evaluating transaction :' + error); } } /** * evaluateBalance * @param {string} network - provide network to which you want to evaluate balance for. * @param {string} enrollmentID - provide enrollment id in string. * @param {string} privateKeyString - Provide PEM format private key. * @param {string} cert - Provide certificate. * @param {string} channelName - provide channelName in string. * @param {string} chainCodeName - provide chainCodeName in string. * @param {string} transactionName - provide transactionName in string. * @param {Array} transactionParams - Provide transactionParams (enrollment id) in an array. */ const evaluateBalance = async (network, gatewayURL, enrollmentID, privateKeyString, cert, channelName, chainCodeName, transactionNameBalance, transactionParamsBalance) => { try { const domainName = gatewayURL || GetKalpGatewayUrl(network); const proposalUrl = domainName + '/proposal'; const evaluateUrl = domainName + '/evaluate'; const transaction = { enrollmentID: enrollmentID, cert: cert, channelName: channelName, chainCodeName: chainCodeName, transactionName: transactionNameBalance, transactionParams: transactionParamsBalance, }; const balance = await evaluateSignedTransaction(privateKeyString, proposalUrl, evaluateUrl, transaction); return balance; } catch (error) { throw new Error('An error occurred while getting balance :' + error); } }; //Common logic for Evaluate transaction function async function evaluateSignedTransaction(privateKeyString, proposalUrl, evaluateUrl, transaction) { try { const proposalData = await restCall(proposalUrl, transaction); let sigr = ''; let sigs = ''; const proposal = proposalData.message.proposal; const proposalBytes = await decodeBase64String(proposal); [sigr, sigs] = await signUsingElliptic(privateKeyString, proposalBytes); const signedProposal = { signedR: sigr, signedS: sigs, proposal: proposal, }; const evaluateData = await restCall(evaluateUrl, signedProposal); const transactionEvaluate = evaluateData.message.evaluate; return transactionEvaluate; } catch (error) { throw new Error('An error occurred while evaluateSignedTransaction :' + error); } } //restCall async function restCall(url, message) { try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': CONTENT_TYPE }, body: JSON.stringify(message), }); const responseData = await response.json(); if (!response.ok) { if (responseData !== null || '') { throw new Error(`An error occurred while pinging url: ${url}, message: ${JSON.stringify(responseData)}`); } throw new Error(`An error occurred while pinging url: ${url}`); } else { return responseData; } } catch (error) { throw new Error('An error occurred in restCall :' + error); } } //base64string => []bytes , similar to golang async function decodeBase64String(base64String) { try { const base64Table = BASE_64_TABLE; // Prepare a map for reverse lookup const decodeMap = {}; for (let i = 0; i < base64Table.length; i++) { decodeMap[base64Table[i]] = i; } decodeMap['='] = 0; // Decode Base64 string const data = new Uint8Array(base64String.length); let j = 0; for (let i = 0; i < base64String.length; i += 4) { const b1 = decodeMap[base64String[i]]; const b2 = decodeMap[base64String[i + 1]]; const b3 = decodeMap[base64String[i + 2]]; const b4 = decodeMap[base64String[i + 3]]; data[j] = (b1 << 2) | (b2 >> 4); j++; if (base64String[i + 2] !== '=') { data[j] = (b2 << 4) | (b3 >> 2); j++; } if (base64String[i + 3] !== '=') { data[j] = (b3 << 6) | b4; j++; } } return data.slice(0, j); } catch (error) { throw new Error('An error occurred in decodeBase64String function:' + error); } } //exportPrivateKeyAsPem async function exportPrivateKeyAsPem(privateKey) { try { // Export the key const exportedKey = await crypto.subtle.exportKey(EXPORT_PRIVATE_KEY_FORMAT, privateKey); // Convert the exported key to PEM format const exportedAsString = String.fromCharCode.apply(null, Array.from(new Uint8Array(exportedKey))); const exportedAsBase64 = btoa(exportedAsString); const pemExportedKey = `-----BEGIN PRIVATE KEY-----\n${exportedAsBase64}\n-----END PRIVATE KEY-----\n`; return pemExportedKey; } catch (error) { throw new Error('An error occurred in exportPrivateKeyAsPem function :' + error); } } //importPrivateKey async function importPrivateKey(pem) { try { const pemString = pem .replace(BEGIN_PRIVATE_KEY, '') .replace(END_PRIVATE_KEY, ''); const binaryString = atob(pemString); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } const privateKeyData = bytes.buffer; // Import the private key const privateKey = await crypto.subtle.importKey(EXPORT_PRIVATE_KEY_FORMAT, privateKeyData, { name: SIGN_ALGORITHM, namedCurve: NAMED_CURVE, // Assuming ECDSA with P-256 curve }, true, [SIGN]); return privateKey; } catch (error) { throw new Error('An error occurred in importPrivateKey function :' + error); } } //signUsingElliptic async function signUsingElliptic(privateKeyString, hashedBytesArray) { try { const { prvKeyHex } = KEYUTIL.getKey(privateKeyString); const ecdsa = new EC(P256_SIGN_CURVE); const signKey = ecdsa.keyFromPrivate(prvKeyHex, KEY_PAIR_FORMAT_TYPE); // Convert Uint8Array to Buffer for elliptic const buffer = Buffer.from(hashedBytesArray); const sig = ecdsa.sign(buffer, signKey); const sigr = sig.r.toString(); const sigs = sig.s.toString(); return [sigr, sigs]; } catch (error) { throw new Error('An error occurred in signUsingElliptic function:' + error); } } /** * createRandSUsingPrivateKey * @param {string} privateKeyString - Provide PEM format private key. * @param {string} proposal - Proposal in string format. */ async function getRandSvalue(privateKeyString, proposal) { try { const privateKey = await importPrivateKey(privateKeyString); let sigr = ''; let sigs = ''; const proposalBytes = await decodeBase64String(proposal); [sigr, sigs] = await signUsingElliptic(privateKeyString, proposalBytes); return [sigr, sigs]; } catch (error) { throw new Error('An error occurred while getting R and S value :' + error); } } function getNGChannelName(network) { try { switch (network) { case Network.IntegrationMainnet: return URL_CHANNEL_NAME_INTMAINNET; case Network.Stagenet: return URL_CHANNEL_NAME; case Network.Testnet: return URL_CHANNEL_NAME_TESTNET; default: throw new Error('An error occurred while getting channel name :' + 'invalid environment variable passed'); } } catch (error) { throw error; } } /** * getKeyPairFromPemPrivateKey * @param {string} pemPrivateKey - PEM-encoded EC private key * @returns {{ pemPrivateKey: string, pemPublicKey: string }} */ async function getKeyPairFromPemPrivateKey(pemPrivateKey) { try { const ec = new EC(P256_SIGN_CURVE); // Parse the PEM to get the private key object const parsedKey = KEYUTIL.getKey(pemPrivateKey); // Extract raw private key (hex string) const privHex = parsedKey.prvKeyHex; // Generate EC key pair from private key const key = ec.keyFromPrivate(privHex, KEY_PAIR_FORMAT_TYPE); // Get public key const pubPoint = key.getPublic(); const pubHex = pubPoint.encode(KEY_PAIR_FORMAT_TYPE); // Convert to PEM formats const newPrivateKeyPem = KEYUTIL.getPEM(parsedKey, PRIVATE_KEY_TYPE); const newPublicKeyPem = await convertPublicKeyHexToPem(pubHex); return { pemPrivateKey: newPrivateKeyPem, pemPublicKey: newPublicKeyPem, }; } catch (error) { throw new Error('Failed to extract keypair from PEM private key: ' + error.message); } } function encryptText(text) { return CryptoJS.AES.encrypt(text, ENCRYPTION_KEY).toString(); } function decryptText(ciphertext) { const bytes = CryptoJS.AES.decrypt(ciphertext, ENCRYPTION_KEY); return bytes.toString(CryptoJS.enc.Utf8); } export { Network, createCsr, decryptText, encryptText, enrollCsr, evaluateBalance, evaluateTransaction, getEnrollmentId, getKeyPair, getKeyPairFromPemPrivateKey, getKeyPairFromSeedPhrase, getRandSvalue, getSecret, getSeedPhrase, register, registerAndEnrollUser, signUsingElliptic, submitTransaction }; //# sourceMappingURL=index.mjs.map