@bithomp/xrpl-api
Version:
A Bithomp JavaScript/TypeScript library for interacting with the XRP Ledger
136 lines (135 loc) • 5.71 kB
JavaScript
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;
}
;