'use strict';

require('../../generic/typed-enum.cjs');
var types_generic_typedBytes = require('../../generic/typed-bytes.cjs');
var types_generic_typedString = require('../../generic/typed-string.cjs');
var utils_interfaces = require('../../../utils/interfaces.cjs');
require('../../generic/typed-array.cjs');
require('../../generic/typed-tuple.cjs');
require('../../generic/typed-null.cjs');
var types_generic_option = require('../../generic/option.cjs');
require('../../../utils/types/array.cjs');
var utils_types_iterable = require('../../../utils/types/iterable.cjs');
var utils_types_object = require('../../../utils/types/object.cjs');
var utils_types_bytes = require('../../../utils/types/bytes.cjs');
var utils_inheritance = require('../../../utils/inheritance.cjs');
var utils_encoding_base58 = require('../../../utils/encoding/base-58.cjs');
require('multiformats/bases/base58');
require('varint');
require('../../../utils/encoding/ss-58.cjs');
var types_generic_typedNumber = 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_withFrom = require('../../generic/with-from.cjs');
var types_generic_withProp = require('../../generic/with-prop.cjs');
var types_generic_withProps = require('../../generic/with-props.cjs');
var types_generic_withBase58 = require('../../generic/with-base58.cjs');
var types_generic_withBase58btc = require('../../generic/with-base58btc.cjs');
var types_generic_withMultibase = require('../../generic/with-multibase.cjs');
require('../../offchain-signatures/params/index.cjs');
var types_offchainSignatures_publicKeys_index = require('../../offchain-signatures/public-keys/index.cjs');
var types_offchainSignatures_curveType = require('../../offchain-signatures/curve-type.cjs');
var types_publicKeys_publicKey = require('../../public-keys/public-key.cjs');
require('../../public-keys/public-key-sr25519-value.cjs');
require('../../public-keys/public-key-ed25519-value.cjs');
require('../../public-keys/public-key-secp256k1-value.cjs');
require('../../public-keys/public-key-x25519-value.cjs');
require('../../../vc/crypto/Bls12381BBDT16KeyPairDock2024.cjs');
require('../../../vc/crypto/Bls12381BBDT16MACDock2024.cjs');
require('../../../vc/crypto/Bls12381BBDT16MACProofDock2024.cjs');
require('../../../vc/crypto/Bls12381BBSKeyPairDock2023.cjs');
require('../../../vc/crypto/Bls12381BBSSignatureDock2022.cjs');
require('../../../vc/crypto/Bls12381BBSSignatureDock2023.cjs');
require('../../../vc/crypto/Bls12381BBSSignatureProofDock2022.cjs');
require('../../../vc/crypto/Bls12381BBSSignatureProofDock2023.cjs');
require('../../../vc/crypto/Bls12381BDDT16KeyPairDock2024.cjs');
require('../../../vc/crypto/Bls12381BDDT16MACDock2024.cjs');
require('../../../vc/crypto/Bls12381BDDT16MACProofDock2024.cjs');
require('../../../vc/crypto/Bls12381G2KeyPairDock2022.cjs');
require('../../../vc/crypto/Bls12381PSKeyPairDock2023.cjs');
require('../../../vc/crypto/Bls12381PSSignatureDock2023.cjs');
require('../../../vc/crypto/Bls12381PSSignatureProofDock2023.cjs');
var vc_crypto_constants = require('../../../vc/crypto/constants.cjs');
require('bs58');
require('@juanelas/base64');
require('../../../keypairs/keypair-secp256k1.cjs');
var utils_encoding_multibase = require('../../../utils/encoding/multibase.cjs');
require('../../../vc/crypto/common/CustomLinkedDataSignature.cjs');
require('@stablelib/ed25519');
require('../../signatures/signature-value.cjs');
require('../../signatures/signature.cjs');
require('../../../keypairs/dock-keypair.cjs');
require('@transmute/json-web-signature');
var types_did_document_verificationMethodType = require('./verification-method-type.cjs');
var types_did_document_verificationMethodRef = require('./verification-method-ref.cjs');
var types_did_onchain_typedDid_index = require('../onchain/typed-did/index.cjs');
var types_offchainSignatures_publicKeys_ref = require('../../offchain-signatures/public-keys/ref.cjs');
var types_did_onchain_typedDid_cheqdDid = require('../onchain/typed-did/cheqd-did.cjs');
require('crypto');
require('../../generic/with-base.cjs');
require('../../generic/with-catch-null.cjs');
require('../../generic/with-eq.cjs');
require('../../generic/any-of.cjs');
require('../../../utils/types/set.cjs');
require('blake2b');
require('../../../utils/assert.cjs');
require('../../../utils/error.cjs');
require('../../../utils/types/string.cjs');
require('../../generic/with-from-json-bytes.cjs');
require('../../generic/create-placeholder.cjs');
require('../../../utils/encoding/base-58-btc.cjs');
require('../../offchain-signatures/params/value.cjs');
require('../../offchain-signatures/params/id.cjs');
require('../../generic/typed-uuid.cjs');
require('../../generic/with-from-dock-id.cjs');
require('../onchain/typed-did/did-method-key/did-method-key-public-key.cjs');
require('../../generic/sized.cjs');
require('../../../utils/types/number.cjs');
require('../../generic/with-qualifier.cjs');
require('../onchain/constants.cjs');
require('../onchain/typed-did/signature.cjs');
require('../onchain/typed-did/did-method-key/did-method-key-signature.cjs');
require('../../signatures/signature-ed25519-value.cjs');
require('../../signatures/signature-secp256k1-value.cjs');
require('../../signatures/signature-sr25519-value.cjs');
require('../onchain/typed-did/dock-did-value.cjs');
require('../../generic/utils.cjs');
require('../../generic/typed-bytes-array.cjs');
require('../../offchain-signatures/public-keys/value.cjs');
require('../../offchain-signatures/public-keys/id.cjs');
require('@docknetwork/crypto-wasm-ts');
require('../../../vc/crypto/common/DockCryptoKeyPair.cjs');
require('@docknetwork/crypto-wasm-ts/lib/index.js');
require('../../../vc/crypto/common/DockCryptoSignature.cjs');
require('jsonld-signatures');
require('json-stringify-deterministic');
require('semver/preload.js');
require('base64url');
require('jsonld');
require('../../../vc/jws.cjs');
require('../../../vc/crypto/common/DockCryptoSignatureProof.cjs');
require('elliptic');

class PublicKeyBase58 extends types_generic_withBase58(types_generic_typedBytes) {}

class PublicKeyBase64 extends types_generic_withBase58btc(types_generic_typedBytes) {}

class PublicKeyMultibase extends types_generic_withMultibase(types_generic_typedBytes) {}

class PublicKeyBase58OrMultibase extends PublicKeyBase58 {
  toString() {
    return this.bytes.length === 32 ? super.toString() : `z${super.toString()}`;
  }

  toCheqdPayload() {
    return this.toString();
  }

  static from(val) {
    if (typeof val === 'string' && val.substr(0, 1) === 'z') {
      return PublicKeyBase58OrMultibase.fromBase58(val.substr(1));
    } else if (typeof val === 'string') {
      return PublicKeyBase58OrMultibase.fromBase58(val);
    }

    return new PublicKeyBase58OrMultibase(val);
  }
}

class TypedJsonWebKey extends types_generic_withFrom(
  types_generic_typedStruct,
  (value, fromFn) => fromFn(value),
) {
  static Classes = {
    crv: types_generic_option(types_generic_typedString),
    kty: types_generic_option(types_generic_typedString),
    x: types_generic_option(types_generic_typedString),
  };

  get bytes() {
    return this.toJSONStringBytes();
  }

  static fromBytes(bytes) {
    return this.fromJSON(JSON.parse(utils_types_bytes.u8aToString(bytes)));
  }
}

class PublicKeyMetadata extends types_generic_withFrom(types_generic_typedStruct, (value, from) => {
  const self = from(value);

  if (self?.paramsRef == null && self?.participantId == null) {
    return null;
  } else {
    return self;
  }
}) {
  static Classes = {
    paramsRef: types_generic_option(types_offchainSignatures_publicKeys_ref.DockOrCheqdOffchainSignatureParamsRef),
    curveType: types_offchainSignatures_curveType.CurveType,
    participantId: types_generic_option(types_generic_typedNumber),
  };

  constructor(paramsRef, curveType = new types_offchainSignatures_curveType.CurveTypeBls12381(), ...args) {
    super(paramsRef, curveType, ...args);
  }

  toArgs() {
    const { paramsRef, curveType, participantId } = this;

    return [paramsRef, curveType, participantId];
  }
}

class DockPublicKeyMetadata extends types_generic_withProp(
  PublicKeyMetadata,
  'paramsRef',
  types_offchainSignatures_publicKeys_ref.DockOffchainSignatureParamsRef,
) {}

class CheqdPublicKeyMetadata extends types_generic_withProp(
  PublicKeyMetadata,
  'paramsRef',
  types_offchainSignatures_publicKeys_ref.CheqdOffchainSignatureParamsRef,
) {}

class CheqdTestnetPublicKeyMetadata extends types_generic_withProp(
  PublicKeyMetadata,
  'paramsRef',
  types_offchainSignatures_publicKeys_ref.CheqdTestnetOffchainSignatureParamsRef,
) {}

class CheqdMainnetPublicKeyMetadata extends types_generic_withProp(
  PublicKeyMetadata,
  'paramsRef',
  types_offchainSignatures_publicKeys_ref.CheqdMainnetOffchainSignatureParamsRef,
) {}

class VerificationMethod extends types_generic_withFrom(
  types_generic_typedStruct,
  function from(value, fromFn) {
    return fromFn(
      // eslint-disable-next-line no-use-before-define
      value instanceof CheqdVerificationMethod
        ? value.toVerificationMethod(this)
        : value,
    );
  },
) {
  static Classes = {
    id: types_did_document_verificationMethodRef.VerificationMethodRef,
    type: types_did_document_verificationMethodType.VerificationMethodType,
    controller: types_did_onchain_typedDid_index.NamespaceDid,
    publicKeyBase58: types_generic_option(PublicKeyBase58),
    publicKeyBase64: types_generic_option(PublicKeyBase64),
    publicKeyMultibase: types_generic_option(PublicKeyMultibase),
    publicKeyJwk: types_generic_option(TypedJsonWebKey),
    publicKeyHex: types_generic_option(types_generic_typedBytes),
    metadata: types_generic_option(PublicKeyMetadata),
  };

  isOffchain() {
    return !(
      this.type instanceof types_did_document_verificationMethodType.Ed25519Verification2018Method
      || this.type instanceof types_did_document_verificationMethodType.Ed25519Verification2020Method
      || this.type instanceof types_did_document_verificationMethodType.JsonWebKey2020Method
    );
  }

  publicKeyBytes(fullRepresentation = false) {
    const bytes = (
      this.publicKeyMultibase
      || this.publicKeyBase58
      || this.publicKeyBase64
      || this.publicKeyJwk
      || this.publicKeyHex
    )?.bytes;

    if (bytes == null) {
      throw new Error(
        `Expected either of ${utils_types_iterable.fmtIterable([
          'publicKeyMultibase',
          'publicKeyBase58',
          'publicKeyBase64',
          'publicKeyJwk',
          'publicKeyHex',
        ])} to be specified`,
      );
    }

    if (this.publicKeyMultibase) {
      return (fullRepresentation || bytes.length === 32) ? bytes : bytes.slice(bytes.length - 32);
    }

    return bytes;
  }

  publicKeyClass() {
    switch (this.type.type) {
      case vc_crypto_constants.Ed25519VerKeyName:
        return types_publicKeys_publicKey.PublicKeyEd25519;
      case vc_crypto_constants.Sr25519VerKeyName:
        return types_publicKeys_publicKey.PublicKeySr25519;
      case vc_crypto_constants.Ed255192020VerKeyName:
        return types_publicKeys_publicKey.PublicKeyEd25519;
      case vc_crypto_constants.EcdsaSecp256k1VerKeyName:
        return types_publicKeys_publicKey.PublicKeySecp256k1;
      case vc_crypto_constants.Bls12381BBSDockVerKeyName:
        return types_offchainSignatures_publicKeys_index.BBSPlusPublicKey;
      case vc_crypto_constants.Bls12381BBS23DockVerKeyName:
        return types_offchainSignatures_publicKeys_index.BBSPublicKey;
      case vc_crypto_constants.Bls12381PSDockVerKeyName:
        return types_offchainSignatures_publicKeys_index.PSPublicKey;
      case vc_crypto_constants.Bls12381BBDT16DockVerKeyName:
        return types_offchainSignatures_publicKeys_index.BBDT16PublicKey;
      default:
        throw new Error(`Unknown key type ${this.type.type}`);
    }
  }

  publicKey() {
    const PublicKey = this.publicKeyClass();
    const bytes = this.publicKeyBytes();
    const metaArgs = this.metadata?.toArgs() || [];

    return new PublicKey(new PublicKey.Class(bytes, ...metaArgs));
  }

  static fromDidKey(keyRef, didKey) {
    const ref = types_did_document_verificationMethodRef.VerificationMethodRef.from(keyRef);

    const isJsonWebKey = didKey.publicKey.constructor.VerKeyType === types_did_document_verificationMethodType.JsonWebKey2020Method.Type;
    const pkBytes = utils_types_bytes.valueBytes(didKey.publicKey);
    const isMultibaseKey = !isJsonWebKey && utils_encoding_multibase.isMultibaseBytes(pkBytes);

    return new this(
      ref,
      didKey.publicKey.constructor.VerKeyType,
      ref[0],
      (!isMultibaseKey && !isJsonWebKey) ? pkBytes : void 0,
      void 0,
      isMultibaseKey ? pkBytes : void 0,
      isJsonWebKey ? TypedJsonWebKey.fromBytes(pkBytes) : void 0,
      void 0,
      didKey.isOffchain() ? didKey.publicKey.value : null,
    );
  }

  // eslint-disable-next-line no-use-before-define
  toCheqd(Class = CheqdVerificationMethod) {
    // eslint-disable-next-line no-use-before-define
    return new (utils_inheritance.ensureEqualToOrPrototypeOf(CheqdVerificationMethod, Class))(
      this.id,
      this.controller,
      this.type,
      utils_types_bytes.normalizeToU8a(this.publicKeyBytes(true)),
      this.metadata,
    );
  }

  toJSON() {
    return utils_types_object.filterObj(super.toJSON(), (_, value) => value != null);
  }

  toCheqdPayload() {
    return utils_types_object.filterObj(
      this.apply(utils_interfaces.maybeToCheqdPayloadOrJSON),
      (_, value) => value != null,
    );
  }
}

class CheqdVerificationMethod extends types_generic_withFrom(
  types_generic_typedStruct,
  function from(value, fromFn) {
    if (
      !(value instanceof VerificationMethod)
      && value?.verificationMethodType === types_did_document_verificationMethodType.JsonWebKey2020Method.Type
      && typeof value?.verificationMaterial === 'string'
    ) {
      return fromFn({
        ...value,
        verificationMaterial: utils_types_bytes.stringToU8a(value.verificationMaterial),
      });
    }

    return fromFn(
      value instanceof VerificationMethod ? value.toCheqd(this) : value,
    );
  },
) {
  static Classes = {
    id: types_did_document_verificationMethodRef.CheqdVerificationMethodRef,
    controller: types_did_onchain_typedDid_index.NamespaceDid,
    verificationMethodType: types_did_document_verificationMethodType.VerificationMethodType,
    verificationMaterial: PublicKeyBase58OrMultibase,
    metadata: types_generic_option(PublicKeyMetadata),
  };

  isOffchain() {
    return !(
      this.verificationMethodType instanceof types_did_document_verificationMethodType.Ed25519Verification2018Method
      || this.verificationMethodType instanceof types_did_document_verificationMethodType.Ed25519Verification2020Method
      || this.verificationMethodType instanceof types_did_document_verificationMethodType.JsonWebKey2020Method
    );
  }

  toVerificationMethod(VerMethod = VerificationMethod) {
    // Convert the Cheqd-specific ID to a generic VerificationMethodRef
    const isJsonWebKey = this.verificationMethodType instanceof types_did_document_verificationMethodType.JsonWebKey2020Method;
    const genericId = types_did_document_verificationMethodRef.VerificationMethodRef.from(this.id.toJSON());
    const isMultibaseKey = !isJsonWebKey && utils_encoding_multibase.isMultibaseBytes(this.verificationMaterial);
    return new (utils_inheritance.ensureEqualToOrPrototypeOf(VerificationMethod, VerMethod))(
      genericId,
      this.verificationMethodType,
      this.controller,
      (!isMultibaseKey && !isJsonWebKey) ? this.verificationMaterial : void 0,
      void 0,
      isMultibaseKey ? this.verificationMaterial : void 0,
      isJsonWebKey ? TypedJsonWebKey.fromBytes(this.verificationMaterial) : void 0,
      void 0,
      this.metadata,
    );
  }

  toJSON() {
    return utils_types_object.filterObj(super.toJSON(), (_, value) => value != null);
  }

  // eslint-disable-next-line sonarjs/no-identical-functions
  toCheqdPayload() {
    const payload = utils_types_object.filterObj(
      this.apply(utils_interfaces.maybeToCheqdPayloadOrJSON),
      (_, value) => value != null,
    );

    if (this.verificationMethodType instanceof types_did_document_verificationMethodType.JsonWebKey2020Method) {
      payload.verificationMaterial = utils_types_bytes.u8aToString(this.verificationMaterial);
    }

    return payload;
  }
}

class CheqdVerificationMethodAssertion extends types_generic_withProp(
  VerificationMethod,
  'metadata',
  types_generic_option(CheqdPublicKeyMetadata),
) {
  toCheqdPayload() {
    return JSON.stringify(JSON.stringify(super.toCheqdPayload()));
  }

  static from(obj) {
    return typeof obj === 'string'
      ? super.fromJSON(JSON.parse(JSON.parse(obj)))
      : super.from(obj);
  }
}

class CheqdTestnetVerificationMethod extends types_generic_withProps(
  CheqdVerificationMethod,
  {
    id: types_did_document_verificationMethodRef.CheqdTestnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdTestnetDid,
    metadata: types_generic_option(CheqdTestnetPublicKeyMetadata),
  },
) {}

class CheqdMainnetVerificationMethod extends types_generic_withProps(
  CheqdVerificationMethod,
  {
    id: types_did_document_verificationMethodRef.CheqdMainnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdMainnetDid,
    metadata: types_generic_option(CheqdMainnetPublicKeyMetadata),
  },
) {}

class CheqdMainnetVerificationMethodAssertion extends types_generic_withProps(
  CheqdVerificationMethodAssertion,
  {
    id: types_did_document_verificationMethodRef.CheqdMainnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdMainnetDid,
    metadata: types_generic_option(CheqdMainnetPublicKeyMetadata),
  },
) {}

class CheqdTestnetVerificationMethodAssertion extends types_generic_withProps(
  CheqdVerificationMethodAssertion,
  {
    id: types_did_document_verificationMethodRef.CheqdTestnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdTestnetDid,
    metadata: types_generic_option(CheqdTestnetPublicKeyMetadata),
  },
) {}

class CheqdVerificationMethodAssertionLegacy extends types_generic_withFrom(
  CheqdVerificationMethod,
  (value, from) => {
    const self = from(value);
    const verMethod = self.toVerificationMethod();

    if (verMethod.isOffchain()) {
      let json;
      try {
        json = JSON.parse(utils_types_bytes.u8aToString(verMethod.publicKeyBytes()));
      } catch {
        return self;
      }

      const pk = verMethod.publicKeyClass().from(json);
      self.verificationMaterial = utils_types_bytes.valueBytes(pk.bytes);
      self.metadata = pk.value;
    }

    return self;
  },
) {
  toCheqdPayload() {
    const payload = utils_types_object.filterObj(
      this.apply(utils_interfaces.maybeToCheqdPayloadOrJSON),
      (key, value) => key !== 'metadata' && value != null,
    );

    const verMethod = this.toVerificationMethod();

    if (verMethod.isOffchain()) {
      const pk = verMethod.publicKey();

      if (pk.value.paramsRef != null || pk.value.participantId != null) {
        payload.verificationMaterial = utils_encoding_base58.encodeAsBase58(pk.toJSONStringBytes());
      }
    }

    return JSON.stringify(JSON.stringify(payload));
  }

  // eslint-disable-next-line sonarjs/no-identical-functions
  static from(obj) {
    return typeof obj === 'string'
      ? super.fromJSON(JSON.parse(JSON.parse(obj)))
      : super.from(obj);
  }
}

class CheqdMainnetVerificationMethodAssertionLegacy extends types_generic_withProps(
  CheqdVerificationMethodAssertionLegacy,
  {
    id: types_did_document_verificationMethodRef.CheqdMainnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdMainnetDid,
    metadata: types_generic_option(CheqdMainnetPublicKeyMetadata),
  },
) {}

class CheqdTestnetVerificationMethodAssertionLegacy extends types_generic_withProps(
  CheqdVerificationMethodAssertionLegacy,
  {
    id: types_did_document_verificationMethodRef.CheqdTestnetVerificationMethodRef,
    controller: types_did_onchain_typedDid_cheqdDid.CheqdTestnetDid,
    metadata: types_generic_option(CheqdTestnetPublicKeyMetadata),
  },
) {}

exports.CheqdMainnetPublicKeyMetadata = CheqdMainnetPublicKeyMetadata;
exports.CheqdMainnetVerificationMethod = CheqdMainnetVerificationMethod;
exports.CheqdMainnetVerificationMethodAssertion = CheqdMainnetVerificationMethodAssertion;
exports.CheqdMainnetVerificationMethodAssertionLegacy = CheqdMainnetVerificationMethodAssertionLegacy;
exports.CheqdPublicKeyMetadata = CheqdPublicKeyMetadata;
exports.CheqdTestnetPublicKeyMetadata = CheqdTestnetPublicKeyMetadata;
exports.CheqdTestnetVerificationMethod = CheqdTestnetVerificationMethod;
exports.CheqdTestnetVerificationMethodAssertion = CheqdTestnetVerificationMethodAssertion;
exports.CheqdTestnetVerificationMethodAssertionLegacy = CheqdTestnetVerificationMethodAssertionLegacy;
exports.CheqdVerificationMethod = CheqdVerificationMethod;
exports.CheqdVerificationMethodAssertion = CheqdVerificationMethodAssertion;
exports.CheqdVerificationMethodAssertionLegacy = CheqdVerificationMethodAssertionLegacy;
exports.DockPublicKeyMetadata = DockPublicKeyMetadata;
exports.PublicKeyBase58 = PublicKeyBase58;
exports.PublicKeyBase58OrMultibase = PublicKeyBase58OrMultibase;
exports.PublicKeyBase64 = PublicKeyBase64;
exports.PublicKeyMetadata = PublicKeyMetadata;
exports.PublicKeyMultibase = PublicKeyMultibase;
exports.TypedJsonWebKey = TypedJsonWebKey;
exports.VerificationMethod = VerificationMethod;
//# sourceMappingURL=verification-method.cjs.map
