/// <summary>
 /// Creates SignedTransaction from LogicsigSignature and Transaction.
 /// LogicsigSignature must be valid and verifiable against transaction sender field.
 /// </summary>
 /// <param name="lsig">LogicsigSignature</param>
 /// <param name="tx">Transaction</param>
 /// <returns>SignedTransaction</returns>
 public static SignedTransaction SignLogicsigTransaction(LogicsigSignature lsig, Transaction tx)
 {
     if (!lsig.Verify(tx.sender))
     {
         throw new ArgumentException("verification failed");
     }
     return(new SignedTransaction(tx, lsig, tx.TxID()));
 }
        /// <summary>
        /// Sign LogicSig with account's secret key
        /// </summary>
        /// <param name="lsig">LogicsigSignature to sign</param>
        /// <returns>LogicsigSignature with updated signature</returns>
        public LogicsigSignature SignLogicsig(LogicsigSignature lsig)
        {
            byte[]    bytesToSign = lsig.BytesToSign();
            Signature sig         = this.RawSignBytes(bytesToSign);

            lsig.sig = sig;
            return(lsig);
        }
        /// <summary>
        /// Sign LogicSig as multisig
        /// </summary>
        /// <param name="lsig">LogicsigSignature to sign</param>
        /// <param name="ma">MultisigAddress to format multi signature from</param>
        /// <returns>LogicsigSignature</returns>
        public LogicsigSignature SignLogicsig(LogicsigSignature lsig, MultisigAddress ma)
        {
            var pk      = this.GetEd25519PublicKey();
            int pkIndex = -1;

            for (int i = 0; i < ma.publicKeys.Count; i++)
            {
                if (Enumerable.SequenceEqual(pk.GetEncoded(), ma.publicKeys[i].GetEncoded()))
                {
                    pkIndex = i;
                    break;
                }
            }

            if (pkIndex == -1)
            {
                throw new ArgumentException("Multisig account does not contain this secret key");
            }
            // now, create the multisignature
            byte[]            bytesToSign = lsig.BytesToSign();
            Signature         sig         = this.RawSignBytes(bytesToSign);
            MultisigSignature mSig        = new MultisigSignature(ma.version, ma.threshold);

            for (int i = 0; i < ma.publicKeys.Count; i++)
            {
                if (i == pkIndex)
                {
                    mSig.subsigs.Add(new MultisigSubsig(pk, sig));
                }
                else
                {
                    mSig.subsigs.Add(new MultisigSubsig(ma.publicKeys[i]));
                }
            }
            lsig.msig = mSig;
            return(lsig);
        }
        /// <summary>
        /// Appends a signature to multisig logic signed transaction
        /// </summary>
        /// <param name="lsig">LogicsigSignature append to</param>
        /// <returns>LogicsigSignature</returns>
        public LogicsigSignature AppendToLogicsig(LogicsigSignature lsig)
        {
            var pk      = this.GetEd25519PublicKey();
            int pkIndex = -1;

            for (int i = 0; i < lsig.msig.subsigs.Count; i++)
            {
                MultisigSubsig subsig = lsig.msig.subsigs[i];
                if (Enumerable.SequenceEqual(subsig.key.GetEncoded(), pk.GetEncoded()))
                {
                    pkIndex = i;
                }
            }
            if (pkIndex == -1)
            {
                throw new ArgumentException("Multisig account does not contain this secret key");
            }
            // now, create the multisignature
            byte[]    bytesToSign = lsig.BytesToSign();
            Signature sig         = this.RawSignBytes(bytesToSign);

            lsig.msig.subsigs[pkIndex] = new MultisigSubsig(pk, sig);
            return(lsig);
        }
        /// <summary>
        /// Creates Signature compatible with ed25519verify TEAL opcode from data and program bytes
        /// </summary>
        /// <param name="data">data byte[]</param>
        /// <param name="program">program byte[]</param>
        /// <returns>Signature</returns>
        public Signature TealSignFromProgram(byte[] data, byte[] program)
        {
            LogicsigSignature lsig = new LogicsigSignature(program);

            return(this.TealSign(data, lsig.Address));
        }