"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Address = void 0;
const account_1 = require("./account");
const bytes_1 = require("./bytes");
/**
 * Handling and generating Ethereum addresses
 */
class Address {
    constructor(buf) {
        if (buf.length !== 20) {
            throw new Error('Invalid address length');
        }
        this.buf = buf;
    }
    /**
     * Returns the zero address.
     */
    static zero() {
        return new Address((0, bytes_1.zeros)(20));
    }
    /**
     * Returns an Address object from a hex-encoded string.
     * @param str - Hex-encoded address
     */
    static fromString(str) {
        if (!(0, account_1.isValidAddress)(str)) {
            throw new Error('Invalid address');
        }
        return new Address((0, bytes_1.toBuffer)(str));
    }
    /**
     * Returns an address for a given public key.
     * @param pubKey The two points of an uncompressed key
     */
    static fromPublicKey(pubKey) {
        if (!Buffer.isBuffer(pubKey)) {
            throw new Error('Public key should be Buffer');
        }
        const buf = (0, account_1.pubToAddress)(pubKey);
        return new Address(buf);
    }
    /**
     * Returns an address for a given private key.
     * @param privateKey A private key must be 256 bits wide
     */
    static fromPrivateKey(privateKey) {
        if (!Buffer.isBuffer(privateKey)) {
            throw new Error('Private key should be Buffer');
        }
        const buf = (0, account_1.privateToAddress)(privateKey);
        return new Address(buf);
    }
    /**
     * Generates an address for a newly created contract.
     * @param from The address which is creating this new address
     * @param nonce The nonce of the from account
     */
    static generate(from, nonce) {
        if (typeof nonce !== 'bigint') {
            throw new Error('Expected nonce to be a bigint');
        }
        return new Address((0, account_1.generateAddress)(from.buf, (0, bytes_1.bigIntToBuffer)(nonce)));
    }
    /**
     * Generates an address for a contract created using CREATE2.
     * @param from The address which is creating this new address
     * @param salt A salt
     * @param initCode The init code of the contract being created
     */
    static generate2(from, salt, initCode) {
        if (!Buffer.isBuffer(salt)) {
            throw new Error('Expected salt to be a Buffer');
        }
        if (!Buffer.isBuffer(initCode)) {
            throw new Error('Expected initCode to be a Buffer');
        }
        return new Address((0, account_1.generateAddress2)(from.buf, salt, initCode));
    }
    /**
     * Is address equal to another.
     */
    equals(address) {
        return this.buf.equals(address.buf);
    }
    /**
     * Is address zero.
     */
    isZero() {
        return this.equals(Address.zero());
    }
    /**
     * True if address is in the address range defined
     * by EIP-1352
     */
    isPrecompileOrSystemAddress() {
        const address = (0, bytes_1.bufferToBigInt)(this.buf);
        const rangeMin = BigInt(0);
        const rangeMax = BigInt('0xffff');
        return address >= rangeMin && address <= rangeMax;
    }
    /**
     * Returns hex encoding of address.
     */
    toString() {
        return '0x' + this.buf.toString('hex');
    }
    /**
     * Returns Buffer representation of address.
     */
    toBuffer() {
        return Buffer.from(this.buf);
    }
}
exports.Address = Address;
//# sourceMappingURL=address.js.map