protected function generateComposedTransactionModel($request_id, PaymentAddress $payment_address, $destination, $float_quantity, $asset, $float_fee, $float_btc_dust_size, $is_sweep)
 {
     // check to see if this signed transaction already exists in the database
     $composed_transaction_model = $this->composed_transaction_repository->getComposedTransactionByRequestID($request_id);
     if ($composed_transaction_model === null) {
         // build the signed transactions
         $change_address_collection = null;
         $built_transaction_to_send = $this->buildSignedTransactionToSend($payment_address, $destination, $float_quantity, $asset, $change_address_collection, $float_fee, $float_btc_dust_size, $is_sweep);
         // get the utxo identifiers
         $utxo_identifiers = $this->buildUTXOIdentifiersFromUTXOs($built_transaction_to_send->getInputUtxos());
         // store the signed transactions to the database cache
         $signed_transaction_hex = $built_transaction_to_send->getTransactionHex();
         $txid = $built_transaction_to_send->getTxId();
         $composed_transaction_model = $this->composed_transaction_repository->storeOrFetchComposedTransaction($request_id, $txid, $signed_transaction_hex, $utxo_identifiers);
         // mark each UTXO as spent
         $this->txo_repository->updateByTXOIdentifiers($utxo_identifiers, ['spent' => 1]);
         // create the new UTXOs that belong to any of our addresses
         $account = AccountHandler::getAccount($payment_address);
         $this->clearPaymentAddressInfoCache();
         foreach ($built_transaction_to_send->getOutputUtxos() as $output_utxo) {
             if ($output_utxo['amount'] <= 0) {
                 // don't store OP_RETURN UTXOs with no value
                 continue;
             }
             // create new UTXO
             $utxo_destination_address = AddressFactory::fromOutputScript(ScriptFactory::fromHex($output_utxo['script']))->getAddress();
             list($found_payment_address, $found_account) = $this->loadPaymentAddressInfo($utxo_destination_address);
             if ($found_payment_address) {
                 $this->txo_repository->create($found_payment_address, $found_account, ['txid' => $output_utxo['txid'], 'n' => $output_utxo['n'], 'amount' => $output_utxo['amount'], 'script' => $output_utxo['script'], 'type' => TXO::UNCONFIRMED, 'spent' => 0, 'green' => 1]);
             }
         }
     }
     return $composed_transaction_model;
 }
 public function testComposeP2SHSourceCounterpartyTransaction()
 {
     list($sender_address_1, $wif_key_1, $private_key_1) = $this->newAddressAndKey();
     list($sender_address_2, $wif_key_2, $private_key_2) = $this->newAddressAndKey();
     list($sender_address_3, $wif_key_3, $private_key_3) = $this->newAddressAndKey();
     // build a multisig address (2 of 3)
     $public_keys = [$private_key_1->getPublicKey(), $private_key_2->getPublicKey(), $private_key_3->getPublicKey()];
     $p2sh_script = ScriptFactory::p2sh()->multisig(2, $public_keys);
     $sender_address = $p2sh_script->getAddress()->getAddress();
     // variables
     $utxos = $this->fakeUTXOs($sender_address);
     $asset = 'SOUP';
     $quantity = 45;
     $destination = '1AAAA1111xxxxxxxxxxxxxxxxxxy43CZ9j';
     $fee = 0.0001;
     $btc_dust = 5.432E-5;
     // compose the send
     $composer = new Composer();
     $composed_unsigned_send = $composer->composeSend($asset, CryptoQuantity::fromFloat($quantity), $destination, null, $utxos, $sender_address, $fee, $btc_dust);
     list($txid, $unsigned_hex, $new_utxos) = $this->decomposeComposedTransaction($composed_unsigned_send);
     // parse the signed hex
     $transaction = TransactionFactory::fromHex($unsigned_hex);
     // check output 1
     $tx_output_0 = $transaction->getOutput(0);
     PHPUnit::assertEquals(intval(round($btc_dust * self::SATOSHI)), $tx_output_0->getValue());
     PHPUnit::assertEquals($destination, AddressFactory::fromOutputScript($tx_output_0->getScript())->getAddress());
     // check output 2
     $tx_output_1 = $transaction->getOutput(1);
     $op_return = $tx_output_1->getScript()->getScriptParser()->decode()[1]->getData()->getHex();
     $txid = $transaction->getInput(0)->getOutPoint()->getTxId()->getHex();
     $hex = $this->arc4decrypt($txid, $op_return);
     $expected_hex = '434e54525052545900000000000000000004fadf000000010c388d00';
     PHPUnit::assertEquals($expected_hex, $hex);
     // check output 3
     $tx_output_2 = $transaction->getOutput(2);
     PHPUnit::assertEquals(intval(round((0.123 + 0.0005 - $fee - $btc_dust) * self::SATOSHI)), $tx_output_2->getValue());
     PHPUnit::assertEquals($sender_address, AddressFactory::fromOutputScript($tx_output_2->getScript())->getAddress());
     // check $new_utxos
     PHPUnit::assertNotEmpty($new_utxos);
     PHPUnit::assertEquals(5432, $new_utxos[0]['amount']);
 }