near-ca
Version:
An SDK for controlling Ethereum Accounts from a Near Account.
55 lines (54 loc) • 2.67 kB
JavaScript
;
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));
}