WavesCS - C# client library for Waves API

Many thanks for this.

Hierarchical Key (BIP 32)

In addition, is there any functionality to be able to access some sort of Hierarchical Key generator for your blockchain?

Basically I’m looking at having some sort of Deterministic HierarchicalPrivateKey class that can generate PrivateKeyAccount objects. This way, I do not have to manage a collection of private/public key pairs. I just need one HierarchicalPrivateKey generator object and paths to generate deterministic PrivateKeyAccount objects.

Something similar to the ExtKey class from NBlockchain.

What is the purpose of the “nonce” parameter of the PrivateKeyAccount.CreateFromSeed() method?

Best,
Toyin Akin

That’s exactly what you need.

Awesome, thanks. I will have a play.

It would be good to add a test case showing this (Hierarchical PrivateKeys via nonces) …

Just implemented support for SetScriptTransaction which allows create Smart Accounts. For now this is available on testnet only.

There is a test which compiles and sets simplest script to an account, and then removes it:

Added MultiSig test + limited support of versioned transactions. 2nd version of transfer transaction allows to put several proofs instead of single signature. This version specially activated for this test, by default 1st version (now working on MainNet) is used.

[TestMethod]
public void MultisigTest()
{
  // This test works with tranfer transactions of version 2 only
  TransferTransaction.Version = 2;
  var node = new Node();            

  var script = $@"                
    let aliceSigned = sigVerify(tx.bodyBytes, tx.proofs[0], base58'{Accounts.Alice.PublicKey.ToBase58()}')
    let bobSigned   = sigVerify(tx.bodyBytes, tx.proofs[1], base58'{Accounts.Bob.PublicKey.ToBase58()}')
    aliceSigned && bobSigned";
            
  Console.WriteLine($"Scrit: {script}");
            
  var compiledScript = node.CompileScript(script);
            
  var multiAccount = PrivateKeyAccount.CreateFromSeed(PrivateKeyAccount.GenerateSeed(), AddressEncoding.TestNet);           
  Console.WriteLine("Account generated: {0}", multiAccount.Address);
  node.Transfer(Accounts.Alice, multiAccount.Address, Assets.WAVES, 0.1m);
            
  Thread.Sleep(10000);
            
  Assert.IsTrue(node.GetBalance(multiAccount.Address) == 0.1m);
            
  var setScriptTx = new SetScriptTransaction(multiAccount.PublicKey, compiledScript, 'T');            
  setScriptTx.Sign(multiAccount);
  node.Broadcast(setScriptTx.GetJsonWithSignature());

  Thread.Sleep(10000);
            
  var tx = new TransferTransaction(multiAccount.PublicKey, Accounts.Alice.Address, Assets.WAVES, 0.09m, 0.005m);
  tx.Sign(Accounts.Alice, 0);
  tx.Sign(Accounts.Bob, 1);

  node.Broadcast(tx);
            
  Thread.Sleep(10000);
            
  Assert.IsTrue(node.GetBalance(multiAccount.Address) < 0.02m);
}
1 Like

Nicely done on this library @alexkof

I am currently trying to retrieve transaction history of a specific address, similar to Rest-API method GET /transactions/address/{address}/limit/{limit}. However, I couldn’t find any ways to perform that using this library.

I have tried using node.GetObject(“transactions/address/{0}/limit/10”, account.Address); but it returns an error due incompatible json deserialization.

What is the correct way to do it?

Thanks.

Hi, just added GetTransactionsByAddress() method, check this test:

[TestMethod]
public void TestGetTransactions()
{
  var node = new Node();
  var transactions = node.GetTransationsByAddress(Accounts.Alice.Address, 10);
	
  Assert.IsTrue(transactions.Count() == 10);
  Assert.IsTrue(transactions.All(t => t.GetInt("type") < 20));
  Assert.IsTrue(transactions.All(t => t.GetString("sender").Length > 30));
}

Also, we have pending pull-request with more strong method which parses all transaction types.

1 Like

Hi, this is my PR to WavesCS library: https://github.com/wavesplatform/WavesCS/pull/15/commits

I just add SponsoredFeeTransaction and tests for it + tests for IssueTransaction, ReissueTransaction and BurnTransaction

1 Like

Good day @alexkof, thanks for the Csharp version. it has helped improved my understanding greatly even though I a newbie in BC (blockchain).

Please help me understand how the account is created in BC, I am am following the AccountTest.TestAccountCreation specifically this part PrivateKeyAccount.CreateFromSeed(seed2, AddressEncoding.TestNet); I don’t seem to understand how the address is created in BC, which line of code does the creation, is it hidden? From what I could see is that the Privatekey, Publickey and Address is generated by libraries in the libs folder. Are the libs libraries communicate with Blockchain?

Thanks in advance.

It’s hidden. You generate public and private keys, then derive address from public key. Then you can give your address to someone, and when he sends funds to this address it will appear in blockchain and you will be able to spend funds using your private key.

1 Like

Thank you, i understand

Hi @Putu,

We’ve just added new functionality.

Now you can get the last transactions of a certain address:

    var node = new Node(Node.MainNetHost);
    var limit = 100;
    var address = "3PBmsJXAcgnH9cu81oyW8abNh9jsaNzFQKJ";

    var transactions = node.GetTransactions(address, limit);

You can also get a transaction by its Id:

    var transaction = node.GetTransactionById("37nfgadHFw92hNqzyHFZXmGFo5Wmct6Eik1Y2AdYW1Aq");

Here are some examples of how it can be used.

  1. Get all recent TransferTransactions:
    var transferTransactions = node.GetTransactions(address)
                                   .OfType<TransferTransaction>();
  1. List all distinct recipients of MassTransferTransactions with BTC asset:
    var massTransferBTCRecipients = node.GetTransactions(address)
                                 .OfType<MassTransferTransaction>()
                                 .Where(tx => tx.Asset.Id == Assets.BTC.Id)
                                 .SelectMany(tx => tx.Transfers)
                                 .Select(t => t.Recipient)
                                 .Distinct();
  1. List all recently issued custom assets’ names:
    var customAssetsNames = node.GetTransactions(address)
                                .OfType<IssueTransaction>()
                                .Select(tx => tx.Name);
  1. Calculate the total amount of recently leased assets that are still leased:
    var leasedAmount = node.GetTransactions(address)
                         .OfType<LeaseTransaction>()
                         .Where(tx => tx.IsActive)
                         .Sum(tx => tx.Amount);
  1. Count transactions of each type in recent transactions:
    var transactionsByType = node.GetTransactions(address)
                                 .GroupBy(tx => tx.GetType())
                                 .Select(group => new { Type = group.Key.Name, Count = group.Count() })
                                 .OrderByDescending(x => x.Count);

    foreach (var tx in transactionsByType)
        Console.WriteLine($"{tx.Type}\t\t{tx.Count}");
2 Likes

Cool. Any plan to update the nuget package soon?
When I check this page it was last updated 8 days ago.

Sorry for the delay with an answer, the nuget package is updated (v. 1.1.0.2).

Hi,
is there anyway to query the network with this library so as to get a list of every address with a minimum amount of waves, or even to get every address on waves?
I guess most airdrops already use this, how do i do this with this library?

Thanks

Hi,

I was trying to send TransferTransaction with recipient alias and it fails during signing:

var tx = new TransferTransaction(Accounts.Alice.PublicKey, "alias:T:somealias", Assets.WAVES, 0.001m).Sign(Accounts.Alice);

with exception:

System.ArgumentException: Illegal character l at position 1
    at WavesCS.Base58.Decode(String input) in C:\Projects\WavesCS\WavesCS\Base58.cs:line 98
   at WavesCS.Base58.FromBase58(String data) in C:\Projects\WavesCS\WavesCS\Base58.cs:line 162
   at WavesCS.TransferTransaction.GetBody() in C:\Projects\WavesCS\WavesCS\Transactions\TransferTransaction.cs:line 77
   at WavesCS.TransactionExtensons.Sign[T](T transaction, PrivateKeyAccount account, Int32 proofIndex) in C:\Projects\WavesCS\WavesCS\Transactions\Transaction.cs:line 96

In seems that the problem in the prefix “alias:” itself!

The NuGet package is updated (v. 1.1.0.4):

  • FastHash(byte[] message) was added;
  • Node.GetTransactions was added;
  • We add the possibility to generate Id for Transaction and Order instances;
  • Deserialization of ExchangeTx was fixed (FromJson method).

The NuGet package is updated (v. 1.1.0.5):

  • Add the ability to transfer to aliased addresses.
  • Add Node.GetAssetBalances(address) method.
  • Change tests’ structure.

Hi,

It seems that updated nuget packages v. 1.1.0.4 and v. 1.1.0.5 contain updated source files but the binaries (WavesCS.dll) are old. For example if you try to use nuget v. 1.1.0.5 - there is still no method TransactionExtensons.GenerateId!