@flarenetwork/flare-stake-tool
Version:
Utilities for staking on the Flare network
163 lines • 6.24 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.isAvalancheApp = isAvalancheApp;
exports.isEthereumApp = isEthereumApp;
exports.getPublicKey = getPublicKey;
exports.getCAddress = getCAddress;
exports.getPAddress = getPAddress;
exports.signHash = signHash;
exports.signEvmTransaction = signEvmTransaction;
const hw_app_avalanche_1 = __importDefault(require("@avalabs/hw-app-avalanche"));
const hw_app_eth_1 = require("@ledgerhq/hw-app-eth");
const hw_transport_node_hid_1 = __importDefault(require("@ledgerhq/hw-transport-node-hid"));
const pubk = __importStar(require("../flare/pubk"));
const utils = __importStar(require("../utils"));
async function isAvalancheApp() {
return (await _getAppName()) === "Avalanche";
}
async function isEthereumApp() {
return (await _getAppName()) === "Ethereum";
}
async function _getAppName() {
let appName = "";
await _connect(async (app) => {
const info = await app.getAppInfo();
appName = info.appName;
});
return appName;
}
async function getPublicKey(bip44Path, hrp) {
let account;
await _connect(async (app) => {
account = await app.getAddressAndPubKey(bip44Path, false, hrp);
});
if (!account || !account.publicKey) {
throw new Error("Invalid or missing public key from ledger response");
}
const publicKey = pubk.normalizePublicKey(utils.toHex(account.publicKey));
return publicKey;
}
async function getCAddress(bip44Path, display) {
let account;
await _connect(async (app) => {
account = await app.getETHAddress(bip44Path, display);
});
if (!account) {
throw Error(`Failed to obtain C-chain address from ledger`);
}
return account.address;
}
async function getPAddress(bip44Path, hrp, display) {
let account;
await _connect(async (app) => {
account = await app.getAddressAndPubKey(bip44Path, display, hrp);
});
if (!account) {
throw Error(`Failed to obtain public key from ledger`);
}
return account.address;
}
async function signHash(bip44Path, message) {
const signPath = _getSignPath(bip44Path);
const messageBuffer = utils.toBuffer(message);
let response;
await _connect(async (app) => {
response = await app.signHash(_getAccountPath(bip44Path), [signPath], messageBuffer);
});
if (!response) {
if (response && response.errorMessage !== "No errors") {
throw new Error(`Failed to sign message on ledger: ${response.errorMessage}`);
}
throw new Error(`Failed to sign message on ledger`);
}
const signature = response.signatures?.get(signPath)?.toString("hex");
if (!signature) {
throw new Error("No signature returned from ledger");
}
return signature;
}
async function signEvmTransaction(bip44Path, txHex) {
const rawTx = utils.toHex(txHex, false);
const resolution = await hw_app_eth_1.ledgerService.resolveTransaction(rawTx, {}, {});
let response;
await _connect(async (app) => {
response = await app.signEVMTransaction(bip44Path, rawTx, resolution);
});
if (!response) {
throw new Error("Failed to sign EVM transaction on ledger");
}
if (!response.r || !response.s || !response.v) {
throw new Error("Failed to get signature from ledger device");
}
const r = Buffer.from(utils.toHex(response.r, false), "hex");
const s = Buffer.from(utils.toHex(response.s, false), "hex");
let recoveryParam = parseInt(utils.toHex(response.v, false), 16);
if (recoveryParam === 0 || recoveryParam === 1) {
recoveryParam += 27;
}
else if (recoveryParam > 28) {
recoveryParam = recoveryParam % 2 === 1 ? 27 : 28;
}
const v = Buffer.from(recoveryParam.toString(16), "hex");
const signature = utils.toHex(Buffer.concat([r, s, v]), false);
return signature;
}
async function _connect(execute) {
let avalanche = undefined;
try {
const transport = await hw_transport_node_hid_1.default.open(undefined);
// Two ledger packages have slightly different Transport type definitions
// (abortTimeoutMs optional vs explicitly undefined-able under exactOptionalPropertyTypes).
// The runtime contract is identical.
avalanche = new hw_app_avalanche_1.default(transport);
await execute(avalanche);
}
finally {
if (avalanche && avalanche.transport) {
await avalanche.transport.close();
}
}
}
function _getAccountPath(bip44Path) {
return bip44Path.substring(0, bip44Path.length - 4);
}
function _getSignPath(bip44Path) {
return bip44Path.substring(bip44Path.length - 3);
}
//# sourceMappingURL=avalanche.js.map