"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BtcAddress = void 0;
const bech32_1 = require("../../utils/bech32");
const utils_1 = require("../../utils/utils");
const AddressTypes_1 = require("./AddressTypes");
const UtxoAddress_1 = require("./UtxoAddress");
const AddressBase_1 = require("../AddressBase");
class BtcAddress extends UtxoAddress_1.UtxoAddress {
    get prefix() {
        const prefix = this.privateData[0].toLocaleLowerCase();
        switch (prefix) {
            case "1":
            case "2":
            case "3":
            case "n":
            case "m":
                return prefix;
            case "b":
                if (this.privateData.slice(0, 3).toLocaleLowerCase() == "bc1") {
                    return "bc1";
                }
                return "invalidPrefix";
            case "t":
                if (this.privateData.slice(0, 3).toLocaleLowerCase() == "tb1") {
                    return "tb1";
                }
                return "invalidPrefix";
            default:
                return "invalidPrefix";
        }
    }
    get type() {
        var _a, _b;
        switch (this.prefix) {
            case "1":
                return AddressTypes_1.UtxoAddressTypes.P2PKH;
            case "n":
            case "m":
                return AddressTypes_1.UtxoAddressTypes.TEST_P2PKH;
            case "2":
                return AddressTypes_1.UtxoAddressTypes.TEST_P2SH;
            case "3":
                return AddressTypes_1.UtxoAddressTypes.P2SH;
            case "bc1":
                const version = (_a = (0, bech32_1.bech32Decode)(this.privateData)) === null || _a === void 0 ? void 0 : _a.version;
                if (version == undefined) {
                    return AddressTypes_1.UtxoAddressTypes.INVALID;
                }
                if (version == 0) {
                    if (this.privateData.length == 42)
                        return AddressTypes_1.UtxoAddressTypes.P2WPKH;
                    else if (this.privateData.length == 62)
                        return AddressTypes_1.UtxoAddressTypes.P2WSH;
                    else
                        return AddressTypes_1.UtxoAddressTypes.INVALID;
                }
                else if (version == 1) {
                    return AddressTypes_1.UtxoAddressTypes.P2TR;
                }
                else if (version < 17) {
                    return AddressTypes_1.UtxoAddressTypes.HIGHER_VERSION;
                }
                else
                    return AddressTypes_1.UtxoAddressTypes.INVALID;
            case "tb1":
                const versionT = (_b = (0, bech32_1.bech32Decode)(this.privateData)) === null || _b === void 0 ? void 0 : _b.version;
                if (versionT == undefined) {
                    return AddressTypes_1.UtxoAddressTypes.INVALID;
                }
                if (versionT == 0) {
                    if (this.privateData.length == 42)
                        return AddressTypes_1.UtxoAddressTypes.TEST_P2WPKH;
                    else if (this.privateData.length == 62)
                        return AddressTypes_1.UtxoAddressTypes.TEST_P2WSH;
                    else
                        return AddressTypes_1.UtxoAddressTypes.INVALID;
                }
                else if (versionT == 1) {
                    return AddressTypes_1.UtxoAddressTypes.TEST_P2TR;
                }
                else if (versionT < 17) {
                    return AddressTypes_1.UtxoAddressTypes.TEST_HIGHER_VERSION;
                }
                else
                    return AddressTypes_1.UtxoAddressTypes.INVALID;
            default:
                return AddressTypes_1.UtxoAddressTypes.INVALID;
        }
    }
    get stdHash() {
        if (!this.isValid())
            throw new Error("invalid address");
        switch (this.type) {
            case AddressTypes_1.UtxoAddressTypes.P2PKH:
            case AddressTypes_1.UtxoAddressTypes.P2SH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2PKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2SH:
                return AddressBase_1.AddressBase.toStandardHash((0, utils_1.prefix0x)((0, utils_1.btcBase58Decode)(this.privateData).toString("hex")));
            case AddressTypes_1.UtxoAddressTypes.P2WPKH:
            case AddressTypes_1.UtxoAddressTypes.P2WSH:
            case AddressTypes_1.UtxoAddressTypes.P2TR:
            case AddressTypes_1.UtxoAddressTypes.HIGHER_VERSION:
            case AddressTypes_1.UtxoAddressTypes.TEST_HIGHER_VERSION:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WPKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WSH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2TR:
                const addressHex = (0, bech32_1.bech32AddressToHex2)(this.privateData);
                if (addressHex)
                    return AddressBase_1.AddressBase.toStandardHash((0, utils_1.prefix0x)(addressHex));
                throw new Error("invalid address");
            default:
                throw new Error("invalid address");
        }
    }
    isValid() {
        switch (this.type) {
            case AddressTypes_1.UtxoAddressTypes.P2PKH:
            case AddressTypes_1.UtxoAddressTypes.P2SH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2PKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2SH:
                //invalid length
                if (25 > this.privateData.length || this.privateData.length > 34) {
                    return false;
                }
                if (utils_1.BTC_BASE_58_DICT_regex.test(this.privateData))
                    return false; // contains invalid characters
                // checksum
                return (0, utils_1.btcBase58Checksum)(this.privateData);
            case AddressTypes_1.UtxoAddressTypes.P2WPKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WPKH:
                if ((0, bech32_1.bech32_decode)(this.privateData, "bech32") && this.privateData.length == 42)
                    return true;
                else
                    return false;
            case AddressTypes_1.UtxoAddressTypes.P2WSH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WSH:
                if ((0, bech32_1.bech32_decode)(this.privateData, "bech32") && this.privateData.length == 62)
                    return true;
                else
                    return false;
            case AddressTypes_1.UtxoAddressTypes.P2TR:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2TR:
            case AddressTypes_1.UtxoAddressTypes.HIGHER_VERSION:
            case AddressTypes_1.UtxoAddressTypes.TEST_HIGHER_VERSION:
                if ((0, bech32_1.bech32_decode)(this.privateData, "bech32m"))
                    return true;
                else
                    return false;
            default:
                return false;
        }
    }
    addressToPkscript() {
        if (!this.isValid())
            return "";
        switch (this.type) {
            case AddressTypes_1.UtxoAddressTypes.P2PKH:
            case AddressTypes_1.UtxoAddressTypes.P2SH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2PKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2SH:
                return (0, utils_1.btcBase58AddrToPkScript)(this.privateData);
            case AddressTypes_1.UtxoAddressTypes.P2WPKH:
            case AddressTypes_1.UtxoAddressTypes.P2WSH:
            case AddressTypes_1.UtxoAddressTypes.P2TR:
            case AddressTypes_1.UtxoAddressTypes.HIGHER_VERSION:
            case AddressTypes_1.UtxoAddressTypes.TEST_HIGHER_VERSION:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WPKH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2WSH:
            case AddressTypes_1.UtxoAddressTypes.TEST_P2TR:
                return (0, bech32_1.bech32AddressToPkscript)(this.privateData);
            default:
                return "";
        }
    }
}
exports.BtcAddress = BtcAddress;
//# sourceMappingURL=BtcAddress.js.map