public Task <UTXOChanges> GetUTXOsAsync(DerivationStrategyBase extKey, Bookmark[] confirmedBookmarks, Bookmark[] unconfirmedBookmarks, bool longPolling = true, CancellationToken cancellation = default) { if (extKey == null) { throw new ArgumentNullException(nameof(extKey)); } return(GetUTXOsAsync(TrackedSource.Create(extKey), confirmedBookmarks, unconfirmedBookmarks, longPolling, cancellation)); }
public BitcoinConnector(string oracleAddress, string endpoint, Channel <Deposit> depositStream, Channel <WithdrawInfo> withdrawStream) { this.depositStream = depositStream; this.withdrawStream = withdrawStream; this.oracleAddress = TrackedSource.Create(new BitcoinPubKeyAddress(oracleAddress)); client = new ExplorerClient(new NBXplorerNetworkProvider(NetworkType.Testnet).GetBTC(), new Uri(endpoint)); client.SetNoAuth(); }
public Task <UTXOChanges> GetUTXOsAsync(DerivationStrategyBase extKey, CancellationToken cancellation = default) { if (extKey == null) { throw new ArgumentNullException(nameof(extKey)); } return(GetUTXOsAsync(TrackedSource.Create(extKey), cancellation)); }
private void UpdateTxConfirmations(WalletAddr addr) { var baddr = BitcoinAddress.Create(addr.Address, GetNetwork()); var trackedSource = TrackedSource.Create(baddr); var txs = GetClient().GetTransactions(trackedSource); UpdateTxConfirmations(txs); }
public async Task TrackClaim(PaymentMethodId paymentMethodId, IClaimDestination claimDestination) { var network = _btcPayNetworkProvider.GetNetwork <BTCPayNetwork>(paymentMethodId.CryptoCode); var explorerClient = _explorerClientProvider.GetExplorerClient(network); if (claimDestination is IBitcoinLikeClaimDestination bitcoinLikeClaimDestination) { await explorerClient.TrackAsync(TrackedSource.Create(bitcoinLikeClaimDestination.Address)); } }
public Task <TrackedSource> ConstructTrackedSource() { var data = GetData(); var explorerClient = _nbXplorerClientProvider.GetClient(data.CryptoCode); var factory = explorerClient.Network.DerivationStrategyFactory; if (string.IsNullOrEmpty(data .DerivationStrategy)) { return(Task.FromResult <TrackedSource>(TrackedSource.Create(BitcoinAddress.Create( data.Address, explorerClient.Network.NBitcoinNetwork)))); } else { return(Task.FromResult <TrackedSource>(TrackedSource.Create(_derivationSchemeParser.Parse(factory, data.DerivationStrategy)))); } }
public Task <GetTransactionsResponse> GetTransactionsAsync(DerivationStrategyBase strategy, Bookmark[] confirmedBookmarks, Bookmark[] unconfirmedBookmarks, Bookmark[] replacedBookmarks, bool longPolling, CancellationToken cancellation = default) { return(GetTransactionsAsync(TrackedSource.Create(strategy), confirmedBookmarks, unconfirmedBookmarks, replacedBookmarks, longPolling, cancellation)); }
public Task TrackAsync(DerivationStrategyBase strategy, CancellationToken cancellation = default) { return(TrackAsync(TrackedSource.Create(strategy), cancellation)); }
public Task <GetTransactionsResponse> GetTransactionsAsync(DerivationStrategyBase strategy, CancellationToken cancellation = default) { return(GetTransactionsAsync(TrackedSource.Create(strategy), cancellation)); }
public static void WaitForTransaction(this LongPollingNotificationSession session, BitcoinAddress address, uint256 txId) { session.WaitForTransaction(TrackedSource.Create(address), txId); }
public static void WaitForTransaction(this LongPollingNotificationSession session, DerivationStrategyBase derivationStrategy, uint256 txId) { session.WaitForTransaction(TrackedSource.Create(derivationStrategy), txId); }
BuildModel(EditNBXplorerWalletExternalServiceDataViewModel viewModel, ExternalServiceData mainModel) { var failureViewModel = new EditNBXplorerWalletExternalServiceDataViewModel(viewModel); failureViewModel.CryptoCodes = new SelectList(_nbXplorerOptions.Cryptos?.ToList() ?? new List <string>(), viewModel.CryptoCode); if (viewModel.Action.Equals("add-private-key", StringComparison.InvariantCultureIgnoreCase)) { failureViewModel.PrivateKeys.Add(new PrivateKeyDetails()); return(null, failureViewModel); } if (viewModel.Action.StartsWith("remove-private-key", StringComparison.InvariantCultureIgnoreCase)) { var index = int.Parse(viewModel.Action.Substring(viewModel.Action.IndexOf(":") + 1)); failureViewModel.PrivateKeys.RemoveAt(index); return(null, failureViewModel); } if ((!string.IsNullOrEmpty(viewModel.DerivationStrategy) && !string.IsNullOrEmpty(viewModel.Address)) || string.IsNullOrEmpty(viewModel.DerivationStrategy) && string.IsNullOrEmpty(viewModel.Address)) { ModelState.AddModelError(string.Empty, "Please choose to track either an address OR a derivation scheme"); } var client = _nbXplorerClientProvider.GetClient(viewModel.CryptoCode); BitcoinAddress address = null; DerivationStrategyBase derivationStrategy = null; if (!string.IsNullOrEmpty(viewModel.Address) && !string.IsNullOrEmpty(viewModel.CryptoCode)) { try { var factory = client.Network.DerivationStrategyFactory; address = BitcoinAddress.Create(viewModel.Address, factory.Network); } catch (Exception) { ModelState.AddModelError(nameof(viewModel.Address), "Invalid Address"); } } if (!string.IsNullOrEmpty(viewModel.DerivationStrategy) && !string.IsNullOrEmpty(viewModel.CryptoCode)) { try { var factory = client.Network.DerivationStrategyFactory; derivationStrategy = _derivationSchemeParser.Parse(factory, viewModel.DerivationStrategy); } catch { ModelState.AddModelError(nameof(viewModel.DerivationStrategy), "Invalid Derivation Scheme"); } } //current External Service data var externalServiceData = mainModel; externalServiceData.Set(viewModel); if (!ModelState.IsValid) { return(null, failureViewModel); } if (derivationStrategy != null) { client.Track(TrackedSource.Create(derivationStrategy)); } if (address != null) { client.Track(TrackedSource.Create(address)); } return(externalServiceData, null); }
public async Task <string> WithdrawBtc(string withdrawHash, string recipient, decimal amount) { var coins = new List <UTXO>(); var coinsUsed = new List <UTXO>(); var estimatedFee = await client.GetFeeRateAsync(3); try { await locker.WaitAsync(); while (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) <= amount) { var txOperations = await client.GetUTXOsAsync(TrackedSource.Create(pubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main))); foreach (var op in txOperations.Confirmed.UTXOs) { if (!usedInputs.ContainsKey(op.TransactionHash.ToString() + op.Value.Satoshi.ToString())) { coins.Add(op); } } coins.Sort(delegate(UTXO x, UTXO y) { return(-x.AsCoin().Amount.CompareTo(y.AsCoin().Amount)); }); foreach (var item in coins) { if (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) <= amount) { coinsUsed.Add(item); usedInputs.Add(item.TransactionHash.ToString() + item.Value.Satoshi.ToString(), item); } else { break; } } if (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) < amount) { await Task.Delay(5000); } } TransactionBuilder builder = null; BitcoinPubKeyAddress destination = null; if (network == NetworkType.Testnet) { builder = Network.TestNet.CreateTransactionBuilder(); destination = new BitcoinPubKeyAddress(recipient, Network.TestNet); } else { builder = Network.Main.CreateTransactionBuilder(); destination = new BitcoinPubKeyAddress(recipient, Network.Main); } NBitcoin.Transaction tx = builder .AddCoins(coinsUsed.Select(c => c.AsCoin() /* .ScriptPubKey.ToBytes()*/)) .Send(destination, Money.Coins(amount)) .Send(TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(withdrawHash)), Money.Zero) .SetChange(pubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main)) .SendEstimatedFees((await client.GetFeeRateAsync(3)).FeeRate) .BuildTransaction(sign: false); // Specify the path to unmanaged PKCS#11 library provided by the cryptographic device vendor string pkcs11LibraryPath = @"/opt/cloudhsm/lib/libcloudhsm_pkcs11_standard.so"; // Create factories used by Pkcs11Interop library Net.Pkcs11Interop.HighLevelAPI.Pkcs11InteropFactories factories = new Net.Pkcs11Interop.HighLevelAPI.Pkcs11InteropFactories(); // Load unmanaged PKCS#11 library using (Net.Pkcs11Interop.HighLevelAPI.IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, pkcs11LibraryPath, AppType.MultiThreaded)) { // Show general information about loaded library Net.Pkcs11Interop.HighLevelAPI.ILibraryInfo libraryInfo = pkcs11Library.GetInfo(); Console.WriteLine("Library"); Console.WriteLine(" Manufacturer: " + libraryInfo.ManufacturerId); Console.WriteLine(" Description: " + libraryInfo.LibraryDescription); Console.WriteLine(" Version: " + libraryInfo.LibraryVersion); // Get list of all available slots foreach (Net.Pkcs11Interop.HighLevelAPI.ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent)) { // Show basic information about slot Net.Pkcs11Interop.HighLevelAPI.ISlotInfo slotInfo = slot.GetSlotInfo(); Console.WriteLine(); Console.WriteLine("Slot"); Console.WriteLine(" Manufacturer: " + slotInfo.ManufacturerId); Console.WriteLine(" Description: " + slotInfo.SlotDescription); Console.WriteLine(" Token present: " + slotInfo.SlotFlags.TokenPresent); if (slotInfo.SlotFlags.TokenPresent) { // Show basic information about token present in the slot Net.Pkcs11Interop.HighLevelAPI.ITokenInfo tokenInfo = slot.GetTokenInfo(); Console.WriteLine("Token"); Console.WriteLine(" Manufacturer: " + tokenInfo.ManufacturerId); Console.WriteLine(" Model: " + tokenInfo.Model); Console.WriteLine(" Serial number: " + tokenInfo.SerialNumber); Console.WriteLine(" Label: " + tokenInfo.Label); // Show list of mechanisms (algorithms) supported by the token Console.WriteLine("Supported mechanisms: "); foreach (CKM mechanism in slot.GetMechanismList()) { Console.WriteLine(" " + mechanism); } } using (Net.Pkcs11Interop.HighLevelAPI.ISession session = slot.OpenSession(SessionType.ReadWrite)) { session.Login(CKU.CKU_USER, pkcsUser); // Specify signing mechanism Net.Pkcs11Interop.HighLevelAPI.IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_ECDSA); List <Net.Pkcs11Interop.HighLevelAPI.IObjectAttribute> publicKeyAttributes = new List <Net.Pkcs11Interop.HighLevelAPI.IObjectAttribute>(); publicKeyAttributes.Add(new Net.Pkcs11Interop.HighLevelAPI80.ObjectAttribute(CKA.CKA_LABEL, hsmKey)); publicKeyAttributes.Add(new Net.Pkcs11Interop.HighLevelAPI80.ObjectAttribute(CKA.CKA_SIGN, true)); Net.Pkcs11Interop.HighLevelAPI.IObjectHandle key = session.FindAllObjects(publicKeyAttributes).FirstOrDefault(); uint i = 0; foreach (var c in tx.Inputs.AsIndexedInputs()) { byte[] sourceData = c.GetSignatureHash(coinsUsed.First(cu => cu.Outpoint.Hash == c.PrevOut.Hash).AsCoin()).ToBytes(); Console.WriteLine("sourceData: " + tx.ToHex()); byte[] signature = session.Sign(mechanism, key, sourceData); Console.WriteLine("signature: " + BitConverter.ToString(signature)); var canSig = ECDSASignatureFactory.FromComponents(signature).MakeCanonical(); var sig = new NBitcoin.TransactionSignature(new NBitcoin.Crypto.ECDSASignature(new NBitcoin.BouncyCastle.Math.BigInteger(canSig.R.ToByteArray()), new NBitcoin.BouncyCastle.Math.BigInteger(canSig.S.ToByteArray())), SigHash.Single); builder = builder.AddKnownSignature(pubKey, sig, c.PrevOut); TransactionSignature sig2 = null; if (builder.TrySignInput(tx, i, SigHash.Single, out sig2)) { Console.WriteLine("Input Signed"); Console.WriteLine(BitConverter.ToString(sig2.ToBytes())); } else { Console.WriteLine("Input Not Signed"); } Console.WriteLine("tx: " + tx); i++; tx = builder.SignTransactionInPlace(tx); } Console.WriteLine("tx: " + tx); TransactionPolicyError[] errors = null; if (builder.Verify(tx, out errors)) { var broadcastResult = await client.BroadcastAsync(tx); broadcastResult.ToString(); Console.WriteLine("broadcast: " + tx.GetHash().ToString()); session.Logout(); return(tx.GetHash().ToString()); } else { Console.WriteLine("Verify transaction failed"); } if (errors != null) { foreach (var e in errors) { Console.WriteLine(e.ToString()); } } session.Logout(); } } } return(null); } catch (Exception e) { Log.Error("Failed to send BTC Withdraw" + e.ToString()); throw e; } finally { locker.Release(); } }
public async Task <WithdrawInfo> WithdrawBtc(string withdrawHash, string recipient, decimal amount) { var txOperations = await client.GetUTXOsAsync(TrackedSource.Create(wallet.GetAddress())); var coins = new List <Coin>(); foreach (var op in txOperations.Confirmed.UTXOs) { coins.Add(op.AsCoin()); } coins.Sort(delegate(Coin x, Coin y) { return(-x.Amount.CompareTo(y.Amount)); }); var coinSum = 0m; for (int i = 0; coinSum < amount; i++) { coinSum += coins[i].Amount.ToDecimal(MoneyUnit.BTC); if (coinSum >= amount) { coins.RemoveRange(i + 1, coins.Count - (i + 1)); } } TransactionBuilder builder = null; BitcoinPubKeyAddress destination = null; if (network == NetworkType.Testnet) { builder = Network.TestNet.CreateTransactionBuilder(); destination = new BitcoinPubKeyAddress(recipient, Network.TestNet); } else { builder = Network.Main.CreateTransactionBuilder(); destination = new BitcoinPubKeyAddress(recipient, Network.Main); } NBitcoin.Transaction tx = builder .AddCoins(coins) .AddKeys(wallet) .Send(destination, Money.Coins(amount)) .Send(TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(withdrawHash)), Money.Zero) .SetChange(wallet) .SendFees(Money.Coins(0.0001m)) .BuildTransaction(sign: true); TransactionPolicyError[] errors = null; if (builder.Verify(tx, out errors)) { var broadcastResult = await client.BroadcastAsync(tx); broadcastResult.ToString(); return(new WithdrawInfo() { TxHash = tx.GetHash().ToString(), Timestamp = DateTime.Now }); } if (errors != null) { errors.ToString(); } return(null); }
public async Task <NBXplorerPublicWallet> Get(string cryptoCode, DerivationStrategyBase derivationStrategyBase) { var key = $"{cryptoCode}:{derivationStrategyBase}"; if (_wallets.ContainsKey(key)) { return(_wallets[key]); } _wallets.Add(key, new NBXplorerPublicWallet(_clientProvider.GetClient(cryptoCode), TrackedSource.Create(derivationStrategyBase))); return(await Get(cryptoCode, derivationStrategyBase)); }
public async Task <NBXplorerPublicWallet> Get(string cryptoCode, BitcoinAddress address) { var key = $"{cryptoCode}:{address}"; if (_wallets.ContainsKey(key)) { return(_wallets[key]); } _wallets.Add(key, new NBXplorerPublicWallet(_clientProvider.GetClient(cryptoCode), TrackedSource.Create(address))); return(await Get(cryptoCode, address)); }