UNPKG

@bithomp/xrpl-api

Version:

A Bithomp JavaScript/TypeScript library for interacting with the XRP Ledger

136 lines (135 loc) 5.71 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.classicAddressFromValidatorPK = classicAddressFromValidatorPK; exports.generateSecrets = generateSecrets; exports.sign = sign; exports.verify = verify; exports.verify2 = verify2; const assert = __importStar(require("assert")); const ripple_address_codec_1 = require("ripple-address-codec"); const Crypto = __importStar(require("crypto")); const elliptic_1 = __importDefault(require("elliptic")); const secp256k1 = new elliptic_1.default.ec("secp256k1"); const ed25519 = new elliptic_1.default.eddsa("ed25519"); const rippleKeypairs = __importStar(require("ripple-keypairs")); const utils_1 = require("./parse/utils"); const DER_PRIVATE_KEY_PREFIX = Buffer.from("302E020100300506032B657004220420", "hex"); const DER_PUBLIC_KEY_PREFIX = Buffer.from("302A300506032B6570032100", "hex"); const VALIDATOR_HEX_PREFIX_ED25519 = "ED"; const VALIDATOR_NODE_PUBLIC_KEY_PREFIX = "n"; function classicAddressFromValidatorPK(pk) { let pubkey = pk; if (typeof pk === "string") { pubkey = Buffer.from((0, ripple_address_codec_1.decodeNodePublic)(pk).buffer); } assert.ok(pubkey.length === 33); assert.ok(Crypto.getHashes().includes("sha256")); assert.ok(Crypto.getHashes().includes("ripemd160")); const pubkeyInnerHash = Crypto.createHash("sha256").update(pubkey); const pubkeyOuterHash = Crypto.createHash("ripemd160"); pubkeyOuterHash.update(pubkeyInnerHash.digest()); const accountID = pubkeyOuterHash.digest(); return (0, ripple_address_codec_1.encodeAccountID)(accountID); } function generateSecrets() { const keypair = Crypto.generateKeyPairSync("ed25519", { privateKeyEncoding: { format: "der", type: "pkcs8" }, publicKeyEncoding: { format: "der", type: "spki" }, }); const { privateKey, publicKey } = keypair; const PublicKey = VALIDATOR_HEX_PREFIX_ED25519 + publicKey.slice(DER_PUBLIC_KEY_PREFIX.length, publicKey.length).toString("hex").toUpperCase(); const secretKey = ripple_address_codec_1.codec.encode(privateKey.slice(DER_PRIVATE_KEY_PREFIX.length, privateKey.length), { versions: [0x20], expectedLength: 32, }); return { key_type: "ed25519", secret_key: secretKey, public_key: (0, ripple_address_codec_1.encodeNodePublic)(Buffer.from(PublicKey, "hex")), PublicKey, }; } function sign(message, secret) { if (typeof message === "string") { message = Buffer.from(message, "utf8"); } try { const decoded = ripple_address_codec_1.codec.decode(secret, { versions: [0x20] }); secret = VALIDATOR_HEX_PREFIX_ED25519 + (0, utils_1.bytesToHex)(decoded.bytes.buffer); } catch (_err) { } return rippleKeypairs.sign(message.toString("hex"), secret).toUpperCase(); } function verify(message, signature, publicKey) { if (typeof message === "string") { message = Buffer.from(message, "utf8"); } if (publicKey.slice(0, 1) === VALIDATOR_NODE_PUBLIC_KEY_PREFIX) { const publicKeyBuffer = (0, ripple_address_codec_1.decodeNodePublic)(publicKey); publicKey = (0, utils_1.bytesToHex)(publicKeyBuffer.buffer); } try { return rippleKeypairs.verify(message.toString("hex"), signature, publicKey); } catch (_err) { } return false; } function verify2(message, signature, publicKey) { if (publicKey.slice(0, 1) === VALIDATOR_NODE_PUBLIC_KEY_PREFIX) { const publicKeyBuffer = (0, ripple_address_codec_1.decodeNodePublic)(publicKey); publicKey = (0, utils_1.bytesToHex)(publicKeyBuffer.buffer); } if (publicKey.slice(0, 2) === VALIDATOR_HEX_PREFIX_ED25519) { const verifyKey = ed25519.keyFromPublic(publicKey.slice(2), "hex"); if (verifyKey.verify(message.toString("hex"), signature)) { return true; } } else { const computedHash = Crypto.createHash("sha512").update(message).digest().toString("hex").slice(0, 64); const verifyKey = secp256k1.keyFromPublic(publicKey, "hex"); if (verifyKey.verify(computedHash, signature)) { return true; } } return false; }