@solarity/hardhat-migrate
Version:
The simplest way to deploy smart contracts
154 lines (150 loc) • 5.92 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;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.initTrezor = initTrezor;
exports.signWithTrezor = signWithTrezor;
exports.getTrezorAddress = getTrezorAddress;
const errors_1 = require("../../errors");
let trezorInitialized = false;
let cachedAddress = null;
let lastMnemonicIndexAsked = null;
async function initTrezor() {
if (trezorInitialized)
return;
const TrezorConnect = await getTrezorConnect();
try {
await TrezorConnect.init({
manifest: {
email: "developer@example.com",
appUrl: "https://hardhat.org",
},
debug: false,
lazyLoad: true,
transports: ["BridgeTransport", "NodeUsbTransport"],
});
// eslint-disable-next-line no-console
console.log(`
Trezor Settings Configuration Notice
We're applying two important settings to your Trezor device:
1. Device Passphrase Entry
We've set your Trezor to always request passphrase entry directly on the device itself.
This ensures better security as it's currently not possible to enter passphrases through
the console interface.
2. Temporary Safety Check Override
We're temporarily modifying safety checks with the "PromptTemporarily" setting. This is
necessary because some derivation paths used by our application are incorrectly flagged
as "unknown" by the device firmware (reference: Trezor Suite issue #17203 -
https://github.com/trezor/trezor-suite/issues/17203).
The device will prompt you to confirm these changes.
`);
const result = await TrezorConnect.applySettings({
passphrase_always_on_device: true,
safety_checks: "PromptTemporarily",
});
if (!result.success) {
throw new errors_1.MigrateError(`Failed to apply Trezor settings: ${result.payload.error}`);
}
trezorInitialized = true;
}
catch (error) {
throw new errors_1.MigrateError(`Failed to initialize Trezor connection: ${error.message}`);
}
}
async function signWithTrezor(tx, mnemonicIndex = 0) {
if (!trezorInitialized) {
await initTrezor();
}
const trezorTx = {
to: tx.to,
value: tx.value?.toString() || "0",
chainId: Number(tx.chainId),
gasLimit: tx.gasLimit?.toString() || "0",
gasPrice: tx.gasPrice?.toString(),
nonce: tx.nonce?.toString() || "0",
data: tx.data || "0x",
};
const TrezorConnect = await getTrezorConnect();
const result = await TrezorConnect.ethereumSignTransaction({
transaction: trezorTx,
path: getKeyPath(mnemonicIndex),
useEmptyPassphrase: true,
});
if (!result.success) {
let errorMessage = `Failed to sign transaction with Trezor: ${result.payload.error}\n`;
if (result.payload.error.includes("Forbidden key path")) {
errorMessage +=
"\n See following GitHub issue on how to resolve the problem: https://github.com/trezor/trezor-suite/issues/17203 \n\n";
}
throw new errors_1.MigrateError(errorMessage);
}
return result.payload.serializedTx;
}
async function getTrezorAddress(mnemonicIndex = 0) {
if (!trezorInitialized) {
await initTrezor();
}
if (lastMnemonicIndexAsked === mnemonicIndex && cachedAddress) {
return cachedAddress;
}
const TrezorConnect = await getTrezorConnect();
try {
const result = await TrezorConnect.ethereumGetAddress({
path: getKeyPath(mnemonicIndex),
useEmptyPassphrase: true,
});
if (!result.success) {
throw new errors_1.MigrateError(`Failed to get Trezor address: ${result.payload.error}`);
}
lastMnemonicIndexAsked = mnemonicIndex;
cachedAddress = result.payload.address;
return result.payload.address;
}
catch (error) {
throw new errors_1.MigrateError(`Error getting address from Trezor: ${error.message}`);
}
}
function getKeyPath(mnemonicIndex) {
return `m/44'/60'/0'/0/${mnemonicIndex}`;
}
async function getTrezorConnect() {
try {
const mod = await Promise.resolve(`${"@trezor/connect"}`).then(s => __importStar(require(s)));
return mod.default;
}
catch (error) {
throw new errors_1.MigrateError(`An error occurred while importing @trezor/connect (if the module cannot be found, please install it): ${String(error.message || error)}.`);
}
}
//# sourceMappingURL=trezor-integration.js.map