ethers.js/packages/wallet/lib.esm/index.js

177 lines
8.0 KiB
JavaScript
Raw Normal View History

"use strict";
2020-10-19 06:19:16 +03:00
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());
});
};
import { getAddress } from "@ethersproject/address";
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { arrayify, concat, hexDataSlice, isHexString, joinSignature } from "@ethersproject/bytes";
2020-10-19 06:19:16 +03:00
import { hashMessage, _TypedDataEncoder } from "@ethersproject/hash";
import { defaultPath, HDNode, entropyToMnemonic } from "@ethersproject/hdnode";
import { keccak256 } from "@ethersproject/keccak256";
import { defineReadOnly, resolveProperties } from "@ethersproject/properties";
import { randomBytes } from "@ethersproject/random";
import { SigningKey } from "@ethersproject/signing-key";
2020-02-27 22:58:05 +03:00
import { decryptJsonWallet, decryptJsonWalletSync, encryptKeystore } from "@ethersproject/json-wallets";
import { computeAddress, recoverAddress, serialize } from "@ethersproject/transactions";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
function isAccount(value) {
return (value != null && isHexString(value.privateKey, 32) && value.address != null);
}
2020-01-19 05:48:12 +03:00
function hasMnemonic(value) {
const mnemonic = value.mnemonic;
return (mnemonic && mnemonic.phrase);
}
export class Wallet extends Signer {
constructor(privateKey, provider) {
logger.checkNew(new.target, Wallet);
super();
if (isAccount(privateKey)) {
2019-11-20 12:57:38 +03:00
const signingKey = new SigningKey(privateKey.privateKey);
defineReadOnly(this, "_signingKey", () => signingKey);
defineReadOnly(this, "address", computeAddress(this.publicKey));
if (this.address !== getAddress(privateKey.address)) {
2020-04-24 06:35:39 +03:00
logger.throwArgumentError("privateKey/address mismatch", "privateKey", "[REDACTED]");
}
2020-01-19 05:48:12 +03:00
if (hasMnemonic(privateKey)) {
const srcMnemonic = privateKey.mnemonic;
defineReadOnly(this, "_mnemonic", () => ({
phrase: srcMnemonic.phrase,
path: srcMnemonic.path || defaultPath,
locale: srcMnemonic.locale || "en"
}));
const mnemonic = this.mnemonic;
const node = HDNode.fromMnemonic(mnemonic.phrase, null, mnemonic.locale).derivePath(mnemonic.path);
if (computeAddress(node.privateKey) !== this.address) {
2020-04-24 06:35:39 +03:00
logger.throwArgumentError("mnemonic/address mismatch", "privateKey", "[REDACTED]");
}
}
else {
defineReadOnly(this, "_mnemonic", () => null);
}
}
else {
if (SigningKey.isSigningKey(privateKey)) {
2020-07-13 15:03:56 +03:00
/* istanbul ignore if */
if (privateKey.curve !== "secp256k1") {
logger.throwArgumentError("unsupported curve; must be secp256k1", "privateKey", "[REDACTED]");
}
defineReadOnly(this, "_signingKey", () => privateKey);
}
else {
2020-11-23 06:44:33 +03:00
// A lot of common tools do not prefix private keys with a 0x (see: #1166)
if (typeof (privateKey) === "string") {
if (privateKey.match(/^[0-9a-f]*$/i) && privateKey.length === 64) {
privateKey = "0x" + privateKey;
}
}
2019-11-20 12:57:38 +03:00
const signingKey = new SigningKey(privateKey);
defineReadOnly(this, "_signingKey", () => signingKey);
}
defineReadOnly(this, "_mnemonic", () => null);
defineReadOnly(this, "address", computeAddress(this.publicKey));
}
2020-07-13 15:03:56 +03:00
/* istanbul ignore if */
if (provider && !Provider.isProvider(provider)) {
logger.throwArgumentError("invalid provider", "provider", provider);
}
defineReadOnly(this, "provider", provider || null);
}
get mnemonic() { return this._mnemonic(); }
get privateKey() { return this._signingKey().privateKey; }
get publicKey() { return this._signingKey().publicKey; }
getAddress() {
return Promise.resolve(this.address);
}
connect(provider) {
return new Wallet(this, provider);
}
signTransaction(transaction) {
return resolveProperties(transaction).then((tx) => {
if (tx.from != null) {
if (getAddress(tx.from) !== this.address) {
2020-07-13 15:03:56 +03:00
logger.throwArgumentError("transaction from address mismatch", "transaction.from", transaction.from);
}
delete tx.from;
}
2019-11-20 12:57:38 +03:00
const signature = this._signingKey().signDigest(keccak256(serialize(tx)));
return serialize(tx, signature);
});
}
signMessage(message) {
2020-10-19 06:19:16 +03:00
return __awaiter(this, void 0, void 0, function* () {
return joinSignature(this._signingKey().signDigest(hashMessage(message)));
});
}
_signTypedData(domain, types, value) {
return __awaiter(this, void 0, void 0, function* () {
// Populate any ENS names
const populated = yield _TypedDataEncoder.resolveNames(domain, types, value, (name) => {
if (this.provider == null) {
logger.throwError("cannot resolve ENS names without a provider", Logger.errors.UNSUPPORTED_OPERATION, {
2020-11-17 07:07:24 +03:00
operation: "resolveName",
value: name
2020-10-19 06:19:16 +03:00
});
}
return this.provider.resolveName(name);
});
return joinSignature(this._signingKey().signDigest(_TypedDataEncoder.hash(populated.domain, types, populated.value)));
});
}
encrypt(password, options, progressCallback) {
if (typeof (options) === "function" && !progressCallback) {
progressCallback = options;
options = {};
}
if (progressCallback && typeof (progressCallback) !== "function") {
throw new Error("invalid callback");
}
if (!options) {
options = {};
}
return encryptKeystore(this, password, options, progressCallback);
}
/**
* Static methods to create Wallet instances.
*/
static createRandom(options) {
let entropy = randomBytes(16);
if (!options) {
options = {};
}
if (options.extraEntropy) {
entropy = arrayify(hexDataSlice(keccak256(concat([entropy, options.extraEntropy])), 0, 16));
}
2019-11-20 12:57:38 +03:00
const mnemonic = entropyToMnemonic(entropy, options.locale);
return Wallet.fromMnemonic(mnemonic, options.path, options.locale);
}
static fromEncryptedJson(json, password, progressCallback) {
return decryptJsonWallet(json, password, progressCallback).then((account) => {
return new Wallet(account);
});
}
2020-02-27 22:58:05 +03:00
static fromEncryptedJsonSync(json, password) {
return new Wallet(decryptJsonWalletSync(json, password));
}
static fromMnemonic(mnemonic, path, wordlist) {
if (!path) {
path = defaultPath;
}
return new Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist).derivePath(path));
}
}
export function verifyMessage(message, signature) {
return recoverAddress(hashMessage(message), signature);
}
2020-10-23 03:01:18 +03:00
export function verifyTypedData(domain, types, value, signature) {
return recoverAddress(_TypedDataEncoder.hash(domain, types, value), signature);
}
2020-07-13 15:03:56 +03:00
//# sourceMappingURL=index.js.map