UNPKG

@debridge-finance/solana-utils

Version:

Common utils package to power communication with Solana contracts at deBridge

150 lines 6.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.solidityKeccak256 = exports.keccak256 = void 0; exports.denormalizeAmount = denormalizeAmount; exports.normalizeChainId = normalizeChainId; exports.hashDeployInfo = hashDeployInfo; exports.hashDebridgeId = hashDebridgeId; exports.hashExternalCallBytes = hashExternalCallBytes; exports.hashSubmissionIdRaw = hashSubmissionIdRaw; const tslib_1 = require("tslib"); const buffer_1 = require("buffer"); const web3_js_1 = require("@solana/web3.js"); const bn_js_1 = tslib_1.__importDefault(require("bn.js")); const js_sha3_1 = require("js-sha3"); const helpers_1 = require("./helpers"); const interfaces_1 = require("./interfaces"); const constants_1 = require("./constants"); const solidityPack_1 = require("./solidityPack"); const keccak256 = (data) => `0x${(0, js_sha3_1.keccak256)(data)}`; exports.keccak256 = keccak256; const solidityKeccak256 = (types, values) => { const packed = (0, solidityPack_1.solidityPack)(types, values); return (0, exports.keccak256)(packed); }; exports.solidityKeccak256 = solidityKeccak256; function denormalizeAmount(amount, denominator) { const denominatorBN = new bn_js_1.default(10 ** denominator); return amount.mul(denominatorBN).toArrayLike(buffer_1.Buffer, "be", 32); } function normalizeChainId(chainId) { return (0, helpers_1.hexToBuffer)(`0x${(0, interfaces_1.isBuffer)(chainId) ? chainId.toString("hex") : new bn_js_1.default(chainId).toString(16)}`, 32); } /** * Hashes deploy info * @param params {@link HashDeployInfoParams} * @returns keccak256 of deployInfo structure */ function hashDeployInfo(params) { const nameHash = (0, exports.solidityKeccak256)(["string"], [params.tokenName]); const symbolHash = (0, exports.solidityKeccak256)(["string"], [params.tokenSymbol]); const deployInfoHash = (0, exports.solidityKeccak256)(["uint256", "uint256", "uint256", "uint256", "uint8"], [ constants_1.DEPLOY_INFO_PREFIX, params.debridgeId, nameHash, symbolHash, params.decimals, ]); return deployInfoHash; } /** * Returns bridgeid hash * @param nativeChainId chain id where token originates * @param nativeTokenAddress address of token in native chain in format "0x<HEX STRING>" * @returns bridge id in deBridge network */ function hashDebridgeId(nativeChainId, nativeTokenAddress) { const chainIdBuffer = normalizeChainId(nativeChainId); const bridgeId = (0, exports.solidityKeccak256)(["uint256", "bytes"], [chainIdBuffer, nativeTokenAddress]); return bridgeId; } function hashExternalCallBytes(data) { if (data === undefined || data?.length === 0) { // precomputed "empty" hash return buffer_1.Buffer.from([ 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, ]); } return (0, helpers_1.hexToBuffer)((0, exports.solidityKeccak256)(["bytes"], [data ? data : buffer_1.Buffer.from([])]), 32); } function isSendHashedFlagSet(packedFlags) { const SEND_HASHED_DATA_FLAG_BIT_NUMBER = BigInt(3); const result = (packedFlags >> SEND_HASHED_DATA_FLAG_BIT_NUMBER) & BigInt(1); return result === BigInt(1); } function getShortcutFromAutoParams(params) { const shortcut = params.autoParams?.shortcut; if (shortcut) { return (0, interfaces_1.isBuffer)(shortcut) ? shortcut : (0, helpers_1.hexToBuffer)(shortcut); } else { const flags = BigInt(new bn_js_1.default(params.autoParams?.flags || 0).toNumber()); const data = params.autoParams?.data; if (!data) return hashExternalCallBytes(data); if (isSendHashedFlagSet(flags)) { const result = (0, interfaces_1.isBuffer)(data) ? data : (0, helpers_1.hexToBuffer)(data); if (result.length !== 32) { throw new Error(`Incorrect autoParams.data length for SEND_HASHED_DATA_FLAG`); } return result; } return hashExternalCallBytes(data); } } /** * Hashes submission for provided data * @param params data to hash * @returns submissionId from provided params */ function hashSubmissionIdRaw(params) { let packParams = [ "uint256", // submission prefix "bytes32", // bridge_id "uint256", // source_chain_id "uint256", // target_chain_id "uint256", // amount "bytes", // receiver "uint256", // nonce ]; const receiver = (0, interfaces_1.isBuffer)(params.receiver) ? params.receiver : typeof params.receiver === "string" ? params.receiver.startsWith("0x") ? (0, helpers_1.hexToBuffer)(params.receiver) : new web3_js_1.PublicKey(params.receiver).toBuffer() : new web3_js_1.PublicKey(params.receiver).toBuffer(); let packData = [ constants_1.SUBMISSION_PREFIX, params.debridgeId, // bridge_id normalizeChainId(params.sourceChainId), // source_chain_id normalizeChainId(params.targetChainId), // target_chain_id new bn_js_1.default(params.amount).toArray("be", 32), // amount receiver, // receiver params.nonce, // nonce ]; if (params?.autoParams) { packParams = packParams.concat([ "uint256", // execution fee "uint256", // flag "bytes32", // fallback hash "uint256", // ext call data hash "uint256", // native sender hash ]); const shortcut = getShortcutFromAutoParams(params); const fallback = params.autoParams.fallbackAddress.startsWith("0x") ? (0, helpers_1.hexToBuffer)(params.autoParams.fallbackAddress) : new web3_js_1.PublicKey(params.autoParams.fallbackAddress).toBuffer(); packData = packData.concat([ new bn_js_1.default(params?.autoParams?.executionFee || 0).toArray("be", 32), new bn_js_1.default(params.autoParams?.flags || 0).toArray("be", 32), hashExternalCallBytes(fallback), shortcut, hashExternalCallBytes(params.autoParams.nativeSender), ]); } const submissionIdHash = (0, exports.solidityKeccak256)(packParams, packData); return submissionIdHash; } //# sourceMappingURL=crypto.js.map