'use strict';

var base58 = require('multiformats/bases/base58');
var varint = require('varint');
var types_generic_typedEnum = require('../../../../generic/typed-enum.cjs');
var types_generic_typedBytes = require('../../../../generic/typed-bytes.cjs');
require('../../../../generic/typed-string.cjs');
require('../../../../generic/typed-array.cjs');
require('../../../../generic/typed-tuple.cjs');
require('../../../../generic/typed-null.cjs');
require('../../../../../utils/types/array.cjs');
var utils_types_bytes = require('../../../../../utils/types/bytes.cjs');
require('bs58');
var utils_encoding_base58Btc = require('../../../../../utils/encoding/base-58-btc.cjs');
require('../../../../../utils/encoding/ss-58.cjs');
var types_generic_sized = require('../../../../generic/sized.cjs');
require('../../../../generic/typed-number.cjs');
require('../../../../generic/typed-set.cjs');
require('../../../../generic/typed-map.cjs');
var types_generic_typedStruct = require('../../../../generic/typed-struct.cjs');
require('uuid');
require('js-sha256');
var types_generic_withQualifier = require('../../../../generic/with-qualifier.cjs');
require('../../../../public-keys/public-key.cjs');
require('../../../../public-keys/public-key-sr25519-value.cjs');
var types_publicKeys_publicKeyEd25519Value = require('../../../../public-keys/public-key-ed25519-value.cjs');
var types_publicKeys_publicKeySecp256k1Value = require('../../../../public-keys/public-key-secp256k1-value.cjs');
require('../../../../public-keys/public-key-x25519-value.cjs');
var types_did_onchain_constants = require('../../constants.cjs');
var types_did_onchain_typedDid_signature = require('../signature.cjs');
var types_did_onchain_typedDid_didMethodKey_didMethodKeySignature = require('./did-method-key-signature.cjs');
require('../../../../../utils/types/iterable.cjs');
require('../../../../../utils/types/object.cjs');
require('crypto');
require('../../../../../utils/interfaces.cjs');
require('../../../../../utils/assert.cjs');
require('../../../../../utils/error.cjs');
require('../../../../../utils/inheritance.cjs');
require('../../../../../utils/types/set.cjs');
require('../../../../generic/with-base.cjs');
require('../../../../generic/with-catch-null.cjs');
require('../../../../generic/with-eq.cjs');
require('../../../../generic/any-of.cjs');
require('../../../../generic/with-from.cjs');
require('blake2b');
require('../../../../../utils/types/string.cjs');
require('../../../../generic/with-from-json-bytes.cjs');
require('../../../../generic/create-placeholder.cjs');
require('../../../../../utils/types/number.cjs');
require('../../../../../vc/crypto/constants.cjs');
require('../../../../signatures/signature-value.cjs');
require('../../../../signatures/signature-ed25519-value.cjs');
require('../../../../signatures/signature-secp256k1-value.cjs');
require('../../../../signatures/signature.cjs');
require('../../../../signatures/signature-sr25519-value.cjs');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var varint__default = /*#__PURE__*/_interopDefault(varint);

const Bls12381BBS23DockVerKeyName = 'Bls12381BBSVerificationKeyDock2023';
const Bls12381BBSDockVerKeyName = 'Bls12381G2VerificationKeyDock2022';

class DidMethodKeyPublicKey extends types_generic_withQualifier(types_generic_typedEnum) {
  static Qualifier = types_did_onchain_constants.DidMethodKeyQualifier;

  static Type = 'didMethodKey';

  /**
   * Instantiates `DidMethodKey` from a fully qualified did string.
   * @param {string} did - fully qualified `did:key:*` string
   * @returns {DidMethodKey}
   */
  static fromUnqualifiedString(id) {
    const decoded = base58.base58btc.decode(id);
    varint__default.default.decode(decoded);
    const prefix = decoded.slice(0, varint__default.default.decode.bytes);
    const bytes = decoded.slice(varint__default.default.decode.bytes);
    const hasPrefix = (candidate) => (
      prefix.length === candidate.length
      && prefix.every((byte, idx) => byte === candidate[idx])
    );

    let PublicKey;
    if (hasPrefix(types_did_onchain_constants.DidMethodKeyBytePrefixSecp256k1)) {
      // eslint-disable-next-line no-use-before-define
      PublicKey = DidMethodKeyPublicKeySecp256k1;
    } else if (hasPrefix(types_did_onchain_constants.DidMethodKeyBytePrefixEd25519)) {
      // eslint-disable-next-line no-use-before-define
      PublicKey = DidMethodKeyPublicKeyEd25519;
    } else if (hasPrefix(types_did_onchain_constants.DidMethodKeyBytePrefixBBS23)) {
      // eslint-disable-next-line no-use-before-define
      PublicKey = DidMethodKeyPublicKeyBBS;
    } else if (hasPrefix(types_did_onchain_constants.DidMethodKeyBytePrefixBBSPlus)) {
      // eslint-disable-next-line no-use-before-define
      PublicKey = DidMethodKeyPublicKeyBBSPlus;
    } else {
      throw new Error(`Unsupported \`did:key:*\`: \`${id}\``);
    }

    return new PublicKey(bytes);
  }

  /**
   * Returns unqualified public key encoded in `BS58`.
   */
  toEncodedString() {
    const prefix = this.constructor.Prefix;
    const publicKey = this.value.bytes;

    return utils_encoding_base58Btc.encodeAsBase58btc(prefix, publicKey);
  }

  /**
   * Creates a new `DidMethodKey` from the supplied keypair.
   *
   * @param {DockKeypair} keypair
   * @returns {DidMethodKey}
   */
  static fromKeypair(keypair) {
    if (keypair?.type === Bls12381BBS23DockVerKeyName) {
      // eslint-disable-next-line no-use-before-define
      return new DidMethodKeyPublicKeyBBS(utils_types_bytes.normalizeToU8a(keypair.publicKeyBuffer));
    } else if (keypair?.type === Bls12381BBSDockVerKeyName) {
      // eslint-disable-next-line no-use-before-define
      return new DidMethodKeyPublicKeyBBSPlus(
        utils_types_bytes.normalizeToU8a(keypair.publicKeyBuffer),
      );
    }

    return this.from(keypair.publicKey().value);
  }

  signWith(keyPair, bytes) {
    if (!this.eq(this.constructor.fromKeypair(keyPair))) {
      throw new Error('Expected keypair that has the same key as in `this`');
    }

    // eslint-disable-next-line no-use-before-define
    return new DidMethodKeySignature(
      // eslint-disable-next-line no-use-before-define
      new DidMethodKeySignatureValueObject(this, keyPair.sign(bytes)),
    );
  }
}

class DidMethodKeySignatureValueObject extends types_generic_typedStruct {
  static Classes = {
    didMethodKey: DidMethodKeyPublicKey,
    sig: types_did_onchain_typedDid_didMethodKey_didMethodKeySignature.DidMethodKeySignatureValue,
  };
}

class DidMethodKeySignature extends types_did_onchain_typedDid_signature {
  static Type = 'didMethodKeySignature';

  static Class = DidMethodKeySignatureValueObject;
}

class DidMethodKeyPublicKeyEd25519 extends DidMethodKeyPublicKey {
  static Class = types_publicKeys_publicKeyEd25519Value;

  static Type = types_publicKeys_publicKeyEd25519Value.Type;

  static Prefix = types_did_onchain_constants.DidMethodKeyBytePrefixEd25519;
}

class DidMethodKeyPublicKeySecp256k1 extends DidMethodKeyPublicKey {
  static Class = types_publicKeys_publicKeySecp256k1Value;

  static Type = types_publicKeys_publicKeySecp256k1Value.Type;

  static Prefix = types_did_onchain_constants.DidMethodKeyBytePrefixSecp256k1;
}

class PublicKeyBBSValue extends types_generic_sized(types_generic_typedBytes) {
  static Type = 'bbs';

  static Size = types_did_onchain_constants.DidMethodKeyBBS23ByteSize;

  static VerKeyType = Bls12381BBS23DockVerKeyName;
}

class PublicKeyBBSPlusValue extends types_generic_sized(types_generic_typedBytes) {
  static Type = 'bbsPlus';

  static Size = types_did_onchain_constants.DidMethodKeyBBSPlusByteSize;

  static VerKeyType = Bls12381BBSDockVerKeyName;
}

class DidMethodKeyPublicKeyBBS extends DidMethodKeyPublicKey {
  static Class = PublicKeyBBSValue;

  static Type = PublicKeyBBSValue.Type;

  static Prefix = types_did_onchain_constants.DidMethodKeyBytePrefixBBS23;
}

class DidMethodKeyPublicKeyBBSPlus extends DidMethodKeyPublicKey {
  static Class = PublicKeyBBSPlusValue;

  static Type = PublicKeyBBSPlusValue.Type;

  static Prefix = types_did_onchain_constants.DidMethodKeyBytePrefixBBSPlus;
}

DidMethodKeyPublicKey.bindVariants(
  DidMethodKeyPublicKeyEd25519,
  DidMethodKeyPublicKeySecp256k1,
  DidMethodKeyPublicKeyBBS,
  DidMethodKeyPublicKeyBBSPlus,
);

exports.DidMethodKeyPublicKey = DidMethodKeyPublicKey;
exports.DidMethodKeyPublicKeyBBS = DidMethodKeyPublicKeyBBS;
exports.DidMethodKeyPublicKeyBBSPlus = DidMethodKeyPublicKeyBBSPlus;
exports.DidMethodKeyPublicKeyEd25519 = DidMethodKeyPublicKeyEd25519;
exports.DidMethodKeyPublicKeySecp256k1 = DidMethodKeyPublicKeySecp256k1;
exports.DidMethodKeySignature = DidMethodKeySignature;
exports.DidMethodKeySignatureValueObject = DidMethodKeySignatureValueObject;
//# sourceMappingURL=did-method-key-public-key.cjs.map
