@debridge-finance/solana-utils
Version:
Common utils package to power communication with Solana contracts at deBridge
150 lines • 6.39 kB
JavaScript
;
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