Example #1
0
        public static void single_send_partial_tx(string url, PartialTx partialTx)
        {
            var json          = JsonConvert.SerializeObject(partialTx);
            var stringContent = new StringContent(
                json,
                Encoding.UTF8,
                "application/json");

            var req = ApiClient.PostContentAsync(url, stringContent).Result;

            if (req.IsSuccessStatusCode)
            {
                Log.Information("Transaction sent successfully");
            }
            else
            {
                Log.Error("Error sending transaction - status: {status}", req.StatusCode);
                throw new WalletErrorException(WalletError.Hyper);
            }
        }
Example #2
0
        /// Receive an already well formed JSON transaction issuance and finalize the
        /// transaction, adding our receiving output, to broadcast to the rest of the
        /// network.
        public static void receive_json_tx(
            WalletConfig config,
            Keychain keychain,
            PartialTx partialTx
            )
        {
            var(amount, blinding, tx) = PartialTx.read_partial_tx(keychain, partialTx);

            var finalTx = receive_transaction(config, keychain, amount, blinding, tx);

            var txHex = HexUtil.to_hex(Ser.Ser_vec(finalTx));

            //todo:asyncification

            var url = $"{config.CheckNodeApiHttpAddr}/v1/pool/push";

            var json = JsonConvert.SerializeObject(new TxWrapper {
                TxHex = txHex
            });

            var res = ApiClient.PostContentAsync(url, new StringContent(json, Encoding.UTF8, "application/json")).Result;

            if (!res.IsSuccessStatusCode)

            {
                Log.Debug("{statusCode}", res.StatusCode);
                throw new WalletErrorException(WalletError.Node, $"{res.StatusCode}");
            }



            // var res = ApiClient.PostAsync(uri, new JsonContent(new TxWrapper(){tx_hex=tx_hex})).Result;

            //let url = format!("{}/v1/pool/push", config.check_node_api_http_addr.as_str());
            //let _: () = api::client::post(url.as_str(), &TxWrapper { tx_hex: tx_hex
            //})
            //.map_err(|e| Error::Node(e))?;
        }
Example #3
0
        /// Issue a new transaction to the provided sender by spending some of our
        /// walvar
        /// UTXOs. The destination can be "stdout" (for command line) or a URL to the
        /// recipients walvar receiver (to be implemented).
        public static void issue_send_tx(
            WalletConfig config,
            Keychain keychain,
            ulong amount,
            ulong minimumConfirmations,
            string dest,
            uint maxOutputs,
            bool selectionStrategy
            )
        {
            Checker.refresh_outputs(config, keychain);

            var chainTip      = Checker.get_tip_from_node(config);
            var currentHeight = chainTip.Height;

            // proof of concept - set lock_height on the tx
            var lockHeight = chainTip.Height;


            var(tx, blindSum, coins, changeKey) = build_send_tx(
                config,
                keychain,
                amount,
                currentHeight,
                minimumConfirmations,
                lockHeight,
                maxOutputs,
                selectionStrategy);

            var partialTx = PartialTx.build_partial_tx(amount, blindSum, tx);

            // Closure to acquire walvar lock and lock the coins being spent
            // so we avoid accidental double spend attempt.
            void UpdateWallet()
            {
                WalletData.With_wallet(config.DataFileDir, walletData =>
                {
                    foreach (var coin in coins)
                    {
                        walletData.Lock_output(coin);
                    }
                    return(walletData);
                });
            }

            // Closure to acquire walvar lock and devare the change output in case of tx failure.
            void RollbackWallet()
            {
                WalletData.With_wallet(config.DataFileDir, walletData =>
                {
                    Log.Information("cleaning up unused change output from walvar");
                    walletData.Delete_output(changeKey);
                    return(walletData);
                });
            }

            if (dest == "stdout")
            {
                var jsonTx = JsonConvert.SerializeObject(partialTx, Formatting.Indented);

                UpdateWallet();

                Console.WriteLine(jsonTx);
            }
            else if (dest.StartsWith("http"))
            {
                var url = $"{dest}/v1/receive/transaction";

                Log.Debug("Posting partial transaction to {url}", url);

                try
                {
                    Client.send_partial_tx(url, partialTx);
                    UpdateWallet();
                }
                catch
                {
                    Log.Error("Communication with receiver failed. Aborting transaction");
                    RollbackWallet();
                }
            }
            else
            {
                throw new Exception($"dest not in expected format: {dest}");
            }
        }
Example #4
0
 public static void send_partial_tx(string url, PartialTx partialTx)
 {
     single_send_partial_tx(url, partialTx);
 }