ethers.js/packages/hardware-wallets/lib.esm/ledger.js

117 lines
4.9 KiB
JavaScript
Raw Permalink Normal View History

2020-01-10 03:19:21 -05:00
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
2020-01-10 20:09:40 -05:00
import { ethers } from "ethers";
import { version } from "./_version";
const logger = new ethers.utils.Logger(version);
2020-01-10 03:19:21 -05:00
import Eth from "@ledgerhq/hw-app-eth";
// We store these in a separated import so it is easier to swap them out
// at bundle time; browsers do not get HID, for example. This maps a string
// "type" to a Transport with create.
import { transports } from "./ledger-transport";
const defaultPath = "m/44'/60'/0'/0/0";
2020-01-10 20:09:40 -05:00
function waiter(duration) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
}
export class LedgerSigner extends ethers.Signer {
2020-01-10 03:19:21 -05:00
constructor(provider, type, path) {
super();
if (path == null) {
path = defaultPath;
}
if (type == null) {
type = "default";
}
2020-01-10 20:09:40 -05:00
ethers.utils.defineReadOnly(this, "path", path);
ethers.utils.defineReadOnly(this, "type", type);
ethers.utils.defineReadOnly(this, "provider", provider || null);
2020-01-10 03:19:21 -05:00
const transport = transports[type];
if (!transport) {
2020-04-23 23:35:39 -04:00
logger.throwArgumentError("unknown or unsupported type", "type", type);
2020-01-10 03:19:21 -05:00
}
2020-01-10 20:09:40 -05:00
ethers.utils.defineReadOnly(this, "_eth", transport.create().then((transport) => {
2020-01-10 03:19:21 -05:00
const eth = new Eth(transport);
return eth.getAppConfiguration().then((config) => {
return eth;
}, (error) => {
return Promise.reject(error);
});
}, (error) => {
return Promise.reject(error);
}));
}
2020-01-10 20:09:40 -05:00
_retry(callback, timeout) {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
if (timeout && timeout > 0) {
setTimeout(() => { reject(new Error("timeout")); }, timeout);
}
2020-01-10 03:19:21 -05:00
const eth = yield this._eth;
2020-01-10 20:09:40 -05:00
// Wait up to 5 seconds
for (let i = 0; i < 50; i++) {
try {
const result = yield callback(eth);
return resolve(result);
}
catch (error) {
if (error.id !== "TransportLocked") {
return reject(error);
}
}
yield waiter(100);
2020-01-10 03:19:21 -05:00
}
2020-01-10 20:09:40 -05:00
return reject(new Error("timeout"));
}));
}
getAddress() {
return __awaiter(this, void 0, void 0, function* () {
const account = yield this._retry((eth) => eth.getAddress(this.path));
return ethers.utils.getAddress(account.address);
2020-01-10 03:19:21 -05:00
});
}
signMessage(message) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof (message) === 'string') {
2020-01-10 20:09:40 -05:00
message = ethers.utils.toUtf8Bytes(message);
2020-01-10 03:19:21 -05:00
}
2020-01-10 20:09:40 -05:00
const messageHex = ethers.utils.hexlify(message).substring(2);
const sig = yield this._retry((eth) => eth.signPersonalMessage(this.path, messageHex));
2020-01-10 03:19:21 -05:00
sig.r = '0x' + sig.r;
sig.s = '0x' + sig.s;
2020-01-10 20:09:40 -05:00
return ethers.utils.joinSignature(sig);
2020-01-10 03:19:21 -05:00
});
}
signTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
2020-09-05 23:35:35 -04:00
const tx = yield ethers.utils.resolveProperties(transaction);
const baseTx = {
chainId: (tx.chainId || undefined),
data: (tx.data || undefined),
gasLimit: (tx.gasLimit || undefined),
gasPrice: (tx.gasPrice || undefined),
nonce: (tx.nonce ? ethers.BigNumber.from(tx.nonce).toNumber() : undefined),
to: (tx.to || undefined),
value: (tx.value || undefined),
};
const unsignedTx = ethers.utils.serializeTransaction(baseTx).substring(2);
2020-01-10 20:09:40 -05:00
const sig = yield this._retry((eth) => eth.signTransaction(this.path, unsignedTx));
2020-09-05 23:35:35 -04:00
return ethers.utils.serializeTransaction(baseTx, {
v: ethers.BigNumber.from("0x" + sig.v).toNumber(),
2020-01-10 20:09:40 -05:00
r: ("0x" + sig.r),
s: ("0x" + sig.s),
2020-01-10 03:19:21 -05:00
});
});
}
connect(provider) {
return new LedgerSigner(provider, this.type, this.path);
}
}
2020-07-13 08:03:56 -04:00
//# sourceMappingURL=ledger.js.map