UNPKG

@okxweb3/coin-ethereum

Version:

An Ethereum SDK for building Web3 wallets and applications.

71 lines 3.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.recoverFromSignature = exports.ecdsaSign = exports.makeSignature = exports.calculateSigRecovery = exports.isValidSigRecovery = exports.hashPersonalMessage = void 0; const hash_1 = require("./hash"); const helpers_1 = require("./helpers"); const coin_base_1 = require("@okxweb3/coin-base"); const crypto_lib_1 = require("@okxweb3/crypto-lib"); const types_1 = require("./types"); const buffer_1 = require("buffer"); const bytes_1 = require("./bytes"); const eth_sig_util_1 = require("../eth-sig-util"); const util_1 = require("./util"); const hashPersonalMessage = function (message) { (0, helpers_1.assertIsBuffer)(message); const prefix = buffer_1.Buffer.from(`\u0019Ethereum Signed Message:\n${message.length.toString()}`, 'utf-8'); return (0, hash_1.keccak)(buffer_1.Buffer.concat([prefix, message])); }; exports.hashPersonalMessage = hashPersonalMessage; function isValidSigRecovery(recovery) { const rec = new coin_base_1.BN(recovery); return rec.eqn(0) || rec.eqn(1); } exports.isValidSigRecovery = isValidSigRecovery; function calculateSigRecovery(v, chainId) { const vBN = (0, types_1.toType)(v, types_1.TypeOutput.BN); if (!chainId) { return vBN.subn(27); } const chainIdBN = (0, types_1.toType)(chainId, types_1.TypeOutput.BN); return vBN.sub(chainIdBN.muln(2).addn(35)); } exports.calculateSigRecovery = calculateSigRecovery; function makeSignature(v, r, s) { const rSig = (0, bytes_1.fromSigned)(r); const sSig = (0, bytes_1.fromSigned)(s); const vSig = v; const rStr = (0, eth_sig_util_1.padWithZeroes)((0, bytes_1.toUnsigned)(rSig).toString('hex'), 64); const sStr = (0, eth_sig_util_1.padWithZeroes)((0, bytes_1.toUnsigned)(sSig).toString('hex'), 64); const vStr = coin_base_1.base.stripHexPrefix((0, util_1.intToHex)(vSig)); return (0, bytes_1.addHexPrefix)(rStr.concat(sStr, vStr)); } exports.makeSignature = makeSignature; function ecdsaSign(msgHash, privateKey, chainId) { const { signature, recovery } = crypto_lib_1.signUtil.secp256k1.sign(msgHash, privateKey); const r = buffer_1.Buffer.from(signature.slice(0, 32)); const s = buffer_1.Buffer.from(signature.slice(32, 64)); if (chainId && !Number.isSafeInteger(chainId)) { throw new Error('The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)'); } const v = chainId ? recovery + (chainId * 2 + 35) : recovery + 27; return { v, r, s }; } exports.ecdsaSign = ecdsaSign; function recoverFromSignature(msgHash, v, r, s, chainId) { const signature = buffer_1.Buffer.concat([(0, bytes_1.setLengthLeft)(r, 32), (0, bytes_1.setLengthLeft)(s, 32)], 64); const recovery = calculateSigRecovery(v, chainId); if (!isValidSigRecovery(recovery)) { throw new Error('Invalid signature v value'); } const senderPubKey = crypto_lib_1.signUtil.secp256k1.recover(signature, recovery.toNumber(), msgHash, false); if (senderPubKey == null) { throw new Error('ecdsaRecover error'); } const ret = crypto_lib_1.signUtil.secp256k1.publicKeyConvert(senderPubKey, false); if (ret == null) { throw new Error('publicKeyConvert error'); } return ret.slice(1); } exports.recoverFromSignature = recoverFromSignature; //# sourceMappingURL=signature.js.map