"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _create = require("../../../codec/create");

var _Struct = _interopRequireDefault(require("../../../codec/Struct"));

var _constants = require("../constants");

var _ExtrinsicPayload = _interopRequireDefault(require("./ExtrinsicPayload"));

// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

/**
 * @name ExtrinsicSignatureV4
 * @description
 * A container for the [[Signature]] associated with a specific [[Extrinsic]]
 */
class ExtrinsicSignatureV4 extends _Struct.default {
  constructor(value) {
    let {
      isSigned
    } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    super({
      signer: 'Address',
      signature: 'MultiSignature',
      era: 'ExtrinsicEra',
      nonce: 'Compact<Index>',
      tip: 'Compact<Balance>'
    }, ExtrinsicSignatureV4.decodeExtrinsicSignature(value, isSigned));
  }

  static decodeExtrinsicSignature(value) {
    let isSigned = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

    if (!value) {
      return _constants.EMPTY_U8A;
    } else if (value instanceof ExtrinsicSignatureV4) {
      return value;
    }

    return isSigned ? value : _constants.EMPTY_U8A;
  }
  /**
   * @description The length of the value when encoded as a Uint8Array
   */


  get encodedLength() {
    return this.isSigned ? super.encodedLength : 0;
  }
  /**
   * @description `true` if the signature is valid
   */


  get isSigned() {
    return !this.signature.isEmpty;
  }
  /**
   * @description The [[ExtrinsicEra]] (mortal or immortal) this signature applies to
   */


  get era() {
    return this.get('era');
  }
  /**
   * @description The [[Index]] for the signature
   */


  get nonce() {
    return this.get('nonce');
  }
  /**
   * @description The actual [[EcdsaSignature]], [[Ed25519Signature]] or [[Sr25519Signature]]
   */


  get signature() {
    return this.multiSignature.value;
  }
  /**
   * @description The raw [[MultiSignature]]
   */


  get multiSignature() {
    return this.get('signature');
  }
  /**
   * @description The [[Address]] that signed
   */


  get signer() {
    return this.get('signer');
  }
  /**
   * @description The [[Balance]] tip
   */


  get tip() {
    return this.get('tip');
  }

  injectSignature(signer, signature, _ref) {
    let {
      era,
      nonce,
      tip
    } = _ref;
    this.set('era', era);
    this.set('nonce', nonce);
    this.set('signer', signer);
    this.set('signature', signature);
    this.set('tip', tip);
    return this;
  }
  /**
   * @description Adds a raw signature
   */


  addSignature(signer, signature, payload) {
    return this.injectSignature((0, _create.createType)('Address', signer), (0, _create.createType)('MultiSignature', signature), new _ExtrinsicPayload.default(payload));
  }
  /**
   * @description Generate a payload and applies the signature from a keypair
   */


  sign(method, account, _ref2) {
    let {
      blockHash,
      era,
      genesisHash,
      nonce,
      runtimeVersion: {
        specVersion
      },
      tip
    } = _ref2;
    const signer = (0, _create.createType)('Address', account.publicKey);
    const payload = new _ExtrinsicPayload.default({
      blockHash,
      era: era || _constants.IMMORTAL_ERA,
      genesisHash,
      method: method.toHex(),
      nonce,
      specVersion,
      tip: tip || 0
    });
    const signature = (0, _create.createType)('MultiSignature', payload.sign(account));
    return this.injectSignature(signer, signature, payload);
  }
  /**
   * @description Encodes the value as a Uint8Array as per the SCALE specifications
   * @param isBare true when the value has none of the type-specific prefixes (internal)
   */


  toU8a(isBare) {
    return this.isSigned ? super.toU8a(isBare) : _constants.EMPTY_U8A;
  }

}

exports.default = ExtrinsicSignatureV4;