UNPKG

@thorwallet/xchain-ethereum

Version:
184 lines 8.37 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyTypedData = exports.verifyMessage = exports.Wallet = void 0; const tslib_1 = require("tslib"); const address_1 = require("@ethersproject/address"); const abstract_provider_1 = require("@ethersproject/abstract-provider"); const abstract_signer_1 = require("@ethersproject/abstract-signer"); const bytes_1 = require("@ethersproject/bytes"); const hash_1 = require("@ethersproject/hash"); const keccak256_1 = require("@ethersproject/keccak256"); const properties_1 = require("@ethersproject/properties"); const random_1 = require("@ethersproject/random"); const signing_key_1 = require("@ethersproject/signing-key"); const json_wallets_1 = require("@ethersproject/json-wallets"); const transactions_1 = require("@ethersproject/transactions"); const logger_1 = require("@ethersproject/logger"); const hdnode_1 = require("../hdnode/hdnode"); const logger = new logger_1.Logger('THORWALLET_ETHERS_WALLET'); // eslint-disable-next-line @typescript-eslint/no-explicit-any function isAccount(value) { return value != null && bytes_1.isHexString(value.privateKey, 32) && value.address != null; } // eslint-disable-next-line @typescript-eslint/no-explicit-any function hasMnemonic(value) { const mnemonic = value.mnemonic; return mnemonic && mnemonic.phrase; } class Wallet extends abstract_signer_1.Signer { constructor(privateKey, provider) { logger.checkNew(new.target, Wallet); super(); if (isAccount(privateKey)) { const signingKey = new signing_key_1.SigningKey(privateKey.privateKey); properties_1.defineReadOnly(this, '_signingKey', () => signingKey); properties_1.defineReadOnly(this, 'address', transactions_1.computeAddress(this.publicKey)); if (this.address !== address_1.getAddress(privateKey.address)) { logger.throwArgumentError('privateKey/address mismatch', 'privateKey', '[REDACTED]'); } if (hasMnemonic(privateKey)) { const srcMnemonic = privateKey.mnemonic; properties_1.defineReadOnly(this, '_mnemonic', () => ({ phrase: srcMnemonic.phrase, path: srcMnemonic.path || hdnode_1.defaultPath, locale: srcMnemonic.locale || 'en', })); } else { properties_1.defineReadOnly(this, '_mnemonic', () => null); } } else { if (signing_key_1.SigningKey.isSigningKey(privateKey)) { /* istanbul ignore if */ if (privateKey.curve !== 'secp256k1') { logger.throwArgumentError('unsupported curve; must be secp256k1', 'privateKey', '[REDACTED]'); } properties_1.defineReadOnly(this, '_signingKey', () => privateKey); } else { // 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; } } const signingKey = new signing_key_1.SigningKey(privateKey); properties_1.defineReadOnly(this, '_signingKey', () => signingKey); } properties_1.defineReadOnly(this, '_mnemonic', () => null); properties_1.defineReadOnly(this, 'address', transactions_1.computeAddress(this.publicKey)); } /* istanbul ignore if */ if (provider && !abstract_provider_1.Provider.isProvider(provider)) { logger.throwArgumentError('invalid provider', 'provider', provider); } properties_1.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 properties_1.resolveProperties(transaction).then((tx) => { if (tx.from != null) { if (address_1.getAddress(tx.from) !== this.address) { logger.throwArgumentError('transaction from address mismatch', 'transaction.from', transaction.from); } delete tx.from; } const signature = this._signingKey().signDigest(keccak256_1.keccak256(transactions_1.serialize(tx))); return transactions_1.serialize(tx, signature); }); } signMessage(message) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return bytes_1.joinSignature(this._signingKey().signDigest(hash_1.hashMessage(message))); }); } _signTypedData(domain, types, value) { return tslib_1.__awaiter(this, void 0, void 0, function* () { // Populate any ENS names const populated = yield hash_1._TypedDataEncoder.resolveNames(domain, types, value, (name) => { if (this.provider == null) { logger.throwError('cannot resolve ENS names without a provider', logger_1.Logger.errors.UNSUPPORTED_OPERATION, { operation: 'resolveName', value: name, }); } return this.provider.resolveName(name); }); return bytes_1.joinSignature(this._signingKey().signDigest(hash_1._TypedDataEncoder.hash(populated.domain, types, populated.value))); }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any 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 json_wallets_1.encryptKeystore(this, password, options, progressCallback); } /** * Static methods to create Wallet instances. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any static createRandom(options) { return tslib_1.__awaiter(this, void 0, void 0, function* () { let entropy = random_1.randomBytes(16); if (!options) { options = {}; } if (options.extraEntropy) { entropy = bytes_1.arrayify(bytes_1.hexDataSlice(keccak256_1.keccak256(bytes_1.concat([entropy, options.extraEntropy])), 0, 16)); } const mnemonic = yield hdnode_1.entropyToMnemonic(entropy, options.locale); return Wallet.fromMnemonic(mnemonic, options.path, options.locale); }); } static fromEncryptedJson(json, password, progressCallback) { return json_wallets_1.decryptJsonWallet(json, password, progressCallback).then((account) => { return new Wallet(account); }); } static fromEncryptedJsonSync(json, password) { return new Wallet(json_wallets_1.decryptJsonWalletSync(json, password)); } static fromMnemonic(mnemonic, path, wordlist) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!path) { path = hdnode_1.defaultPath; } return new Wallet(yield (yield hdnode_1.HDNode.fromMnemonic(mnemonic, null, wordlist)).derivePath(path)); }); } } exports.Wallet = Wallet; function verifyMessage(message, signature) { return transactions_1.recoverAddress(hash_1.hashMessage(message), signature); } exports.verifyMessage = verifyMessage; function verifyTypedData(domain, types, // eslint-disable-next-line @typescript-eslint/no-explicit-any value, signature) { return transactions_1.recoverAddress(hash_1._TypedDataEncoder.hash(domain, types, value), signature); } exports.verifyTypedData = verifyTypedData; //# sourceMappingURL=wallet.js.map