UNPKG

near-ca

Version:

An SDK for controlling Ethereum Accounts from a Near Account.

55 lines (54 loc) 2.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.najPublicKeyStrToUncompressedHexPoint = najPublicKeyStrToUncompressedHexPoint; exports.deriveChildPublicKey = deriveChildPublicKey; exports.uncompressedHexPointToEvmAddress = uncompressedHexPointToEvmAddress; const serialize_1 = require("near-api-js/lib/utils/serialize"); const elliptic_1 = require("elliptic"); const viem_1 = require("viem"); const js_sha3_1 = require("js-sha3"); /** * Converts a NEAR account public key string to an uncompressed hex point * * @param najPublicKeyStr - The NEAR account public key string * @returns Uncompressed hex point string prefixed with "04" */ function najPublicKeyStrToUncompressedHexPoint(najPublicKeyStr) { const decodedKey = (0, serialize_1.base_decode)(najPublicKeyStr.split(":")[1]); return "04" + Buffer.from(decodedKey).toString("hex"); } /** * Derives a child public key using elliptic curve operations * * @param parentUncompressedPublicKeyHex - Parent public key as uncompressed hex * @param signerId - The signer's identifier * @param path - Optional derivation path (defaults to empty string) * @returns Derived child public key as uncompressed hex string */ function deriveChildPublicKey(parentUncompressedPublicKeyHex, signerId, path = "") { const ec = new elliptic_1.ec("secp256k1"); const scalarHex = (0, js_sha3_1.sha3_256)(`near-mpc-recovery v0.1.0 epsilon derivation:${signerId},${path}`); const x = parentUncompressedPublicKeyHex.substring(2, 66); const y = parentUncompressedPublicKeyHex.substring(66); // Create a point object from X and Y coordinates const oldPublicKeyPoint = ec.curve.point(x, y); // Multiply the scalar by the generator point G const scalarTimesG = ec.g.mul(scalarHex); // Add the result to the old public key point const newPublicKeyPoint = oldPublicKeyPoint.add(scalarTimesG); const newX = newPublicKeyPoint.getX().toString("hex").padStart(64, "0"); const newY = newPublicKeyPoint.getY().toString("hex").padStart(64, "0"); return "04" + newX + newY; } /** * Converts an uncompressed hex point to an Ethereum address * * @param uncompressedHexPoint - The uncompressed hex point string * @returns Ethereum address derived from the public key * @remarks Takes the last 20 bytes of the keccak256 hash of the public key */ function uncompressedHexPointToEvmAddress(uncompressedHexPoint) { const addressHash = (0, viem_1.keccak256)(`0x${uncompressedHexPoint.slice(2)}`); // Ethereum address is last 20 bytes of hash (40 characters), prefixed with 0x return ("0x" + addressHash.substring(addressHash.length - 40)); }