Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d23d0523c | ||
|
|
70c18d119d | ||
|
|
4193bfe000 |
@ -7,9 +7,26 @@ namespace NBXplorer.Models
|
||||
{
|
||||
public class GetBalanceResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// How the confirmed balance would be updated once all the unconfirmed transactions were confirmed.
|
||||
/// </summary>
|
||||
public IMoney Unconfirmed { get; set; }
|
||||
/// <summary>
|
||||
/// The balance of all funds in confirmed transactions.
|
||||
/// </summary>
|
||||
public IMoney Confirmed { get; set; }
|
||||
public IMoney Immature { get; set; }
|
||||
/// <summary>
|
||||
/// The total of funds owned (ie, `confirmed + unconfirmed`)
|
||||
/// </summary>
|
||||
public IMoney Total { get; set; }
|
||||
/// <summary>
|
||||
/// The total unspendable funds (ie, coinbase reward which need 100 confirmations before being spendable)
|
||||
/// </summary>
|
||||
public IMoney Immature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total spendable balance. (ie, `total - immature`)
|
||||
/// </summary>
|
||||
public IMoney Available { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Company>Digital Garage</Company>
|
||||
<Version>4.0.0</Version>
|
||||
<Version>4.0.2</Version>
|
||||
<Copyright>Copyright © Digital Garage 2017</Copyright>
|
||||
<Description>Client API for the minimalist HD Wallet Tracker NBXplorer</Description>
|
||||
<PackageIconUrl>https://aois.blob.core.windows.net/public/Bitcoin.png</PackageIconUrl>
|
||||
@ -24,8 +24,8 @@
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NBitcoin" Version="6.0.3" />
|
||||
<PackageReference Include="NBitcoin.Altcoins" Version="3.0.2" />
|
||||
<PackageReference Include="NBitcoin" Version="6.0.6" />
|
||||
<PackageReference Include="NBitcoin.Altcoins" Version="3.0.3" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
||||
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -36,12 +36,11 @@ namespace NBXplorer.Tests
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void WaitForBlocks(this LongPollingNotificationSession session, params uint256[] txIds)
|
||||
public static void WaitForBlocks(this LongPollingNotificationSession session, params uint256[] blockIds)
|
||||
{
|
||||
if (txIds == null || txIds.Length == 0)
|
||||
if (blockIds == null || blockIds.Length == 0)
|
||||
return;
|
||||
HashSet<uint256> txidsSet = new HashSet<uint256>(txIds);
|
||||
HashSet<uint256> txidsSet = new HashSet<uint256>(blockIds);
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
|
||||
{
|
||||
while (true)
|
||||
|
||||
@ -2663,6 +2663,45 @@ namespace NBXplorer.Tests
|
||||
tester.Notifications.WaitForBlocks(blockId);
|
||||
var savedTx = tester.Client.GetTransaction(txId);
|
||||
Assert.Equal(blockId[0], savedTx.BlockId);
|
||||
|
||||
// Ensure the current state is correct
|
||||
var balance = tester.Client.GetBalance(pubkey);
|
||||
Assert.Equal(Money.Coins(2.5m), balance.Confirmed);
|
||||
Assert.Equal(Money.Coins(0.0m), balance.Unconfirmed);
|
||||
Assert.Equal(Money.Coins(2.5m), balance.Total);
|
||||
Assert.Equal(Money.Coins(0.0m), balance.Immature);
|
||||
Assert.Equal(Money.Coins(2.5m), balance.Available);
|
||||
Logs.Tester.LogInformation("Let's mine, and check that the balance is not updated until maturity occurs");
|
||||
var blkid = tester.RPC.GenerateToAddress(1, tester.AddressOf(key, "0/0"))[0];
|
||||
var blk = tester.RPC.GetBlock(blkid);
|
||||
var minedTxId = blk.Transactions[0].GetHash();
|
||||
tester.Notifications.WaitForTransaction(pubkey, minedTxId);
|
||||
balance = tester.Client.GetBalance(pubkey);
|
||||
Assert.Equal(Money.Coins(52.5m), balance.Confirmed);
|
||||
Assert.Equal(Money.Coins(0.0m), balance.Unconfirmed);
|
||||
Assert.Equal(Money.Coins(52.5m), balance.Total);
|
||||
Assert.Equal(Money.Coins(50.0m), balance.Immature);
|
||||
Assert.Equal(Money.Coins(2.5m), balance.Available);
|
||||
var utxos = tester.Client.GetUTXOs(pubkey);
|
||||
Assert.DoesNotContain(utxos.Confirmed.UTXOs, u => u.Outpoint.Hash == minedTxId);
|
||||
Assert.DoesNotContain(utxos.Unconfirmed.UTXOs, u => u.Outpoint.Hash == minedTxId);
|
||||
var transactions = tester.Client.GetTransactions(pubkey);
|
||||
Assert.Contains(transactions.ConfirmedTransactions.Transactions, u => u.TransactionId == minedTxId);
|
||||
Assert.Contains(transactions.ImmatureTransactions.Transactions, u => u.TransactionId == minedTxId);
|
||||
// Let's generate enough block and see if the transaction is finally mature
|
||||
var blockIds = tester.RPC.Generate(tester.Network.Consensus.CoinbaseMaturity);
|
||||
tester.Notifications.WaitForBlocks(blockIds);
|
||||
balance = tester.Client.GetBalance(pubkey);
|
||||
Assert.Equal(Money.Coins(52.5m), balance.Confirmed);
|
||||
Assert.Equal(Money.Coins(0.0m), balance.Unconfirmed);
|
||||
Assert.Equal(Money.Coins(52.5m), balance.Total);
|
||||
Assert.Equal(Money.Coins(0.0m), balance.Immature);
|
||||
Assert.Equal(Money.Coins(52.5m), balance.Available);
|
||||
transactions = tester.Client.GetTransactions(pubkey);
|
||||
utxos = tester.Client.GetUTXOs(pubkey);
|
||||
Assert.Empty(transactions.ImmatureTransactions.Transactions);
|
||||
Assert.Contains(utxos.Confirmed.UTXOs, u => u.Outpoint.Hash == minedTxId);
|
||||
Assert.Contains(transactions.ConfirmedTransactions.Transactions, u => u.TransactionId == minedTxId);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
|
||||
@ -204,9 +204,8 @@ namespace NBXplorer
|
||||
{
|
||||
if (tx.Height is int)
|
||||
{
|
||||
if(tx.IsMature)
|
||||
ConfirmedTransactions.Add(tx);
|
||||
else
|
||||
ConfirmedTransactions.Add(tx);
|
||||
if (!tx.IsMature)
|
||||
ImmatureTransactions.Add(tx);
|
||||
}
|
||||
else
|
||||
|
||||
@ -858,9 +858,10 @@ namespace NBXplorer.Controllers
|
||||
{
|
||||
Confirmed = CalculateBalance(network, transactions.ConfirmedTransactions),
|
||||
Unconfirmed = CalculateBalance(network, transactions.UnconfirmedTransactions),
|
||||
Immature = CalculateBalance(network,transactions.ImmatureTransactions),
|
||||
};
|
||||
balance.Total = balance.Confirmed.Add(balance.Unconfirmed).Add(balance.Immature);
|
||||
Immature = CalculateBalance(network, transactions.ImmatureTransactions)
|
||||
};
|
||||
balance.Total = balance.Confirmed.Add(balance.Unconfirmed);
|
||||
balance.Available = balance.Total.Sub(balance.Immature);
|
||||
return Json(balance, jsonResult.SerializerSettings);
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">$(TargetFrameworkOverride)</TargetFramework>
|
||||
<Version>2.1.53</Version>
|
||||
<Version>2.1.55</Version>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\NBXplorer.xml</DocumentationFile>
|
||||
<NoWarn>1701;1702;1705;1591;CS1591</NoWarn>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
|
||||
26
docs/API.md
26
docs/API.md
@ -19,8 +19,8 @@ NBXplorer does not index the whole blockchain, rather, it listens transactions a
|
||||
* [Get connection status to the chain](#status)
|
||||
* [Get a new unused address](#unused)
|
||||
* [Get scriptPubKey information of a Derivation Scheme](#scriptPubKey)
|
||||
* [Get Unspent Transaction Outputs (UTXOs)](#utxos)
|
||||
* [Get Unspent Transaction Outputs of a specific address](#address-utxos)
|
||||
* [Get available Unspent Transaction Outputs (UTXOs)](#utxos)
|
||||
* [Get available Unspent Transaction Outputs of a specific address](#address-utxos)
|
||||
* [Notifications via websocket](#websocket)
|
||||
* [Broadcast a transaction](#broadcast)
|
||||
* [Rescan a transaction](#rescan)
|
||||
@ -233,15 +233,20 @@ Returns:
|
||||
"replacedBy": "7ec0bcbd3b7685b6bbdb4287a250b64bfcb799dbbbcffa78c00e6cc11185e5f1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"immatureTransactions": {
|
||||
"transactions": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* `replaceable`: `true` if the transaction can be replaced (the transaction has RBF activated, is in the unconfirmed list and is not an intermediate transaction in a chain of unconfirmed transaction)
|
||||
* `replacing`: Only set in the unconfirmed list, and is pointing to a transaction id in the replaced list.
|
||||
* `replacedBy`: Only set in the replaced list, and is pointing to a transaction id in the unconfirmed list.
|
||||
* `immatureTransactions`: Coinbase transactions with less than 100 confirmations.
|
||||
|
||||
Note for liquid, `balanceChange` is an array of [AssetMoney](#liquid).
|
||||
Note that the list of confirmed transaction also include immature transactions.
|
||||
|
||||
## <a name="address-transactions"></a>Query transactions associated to a specific address
|
||||
|
||||
@ -351,11 +356,21 @@ Returns:
|
||||
{
|
||||
"unconfirmed": 110000000,
|
||||
"confirmed": 100000000,
|
||||
"available": 210000000,
|
||||
"immature": 0,
|
||||
"total": 210000000
|
||||
}
|
||||
```
|
||||
Note for liquid, the values are array of [AssetMoney](#liquid).
|
||||
|
||||
* `unconfirmed`: How the confirmed balance would be updated once all the unconfirmed transactions were confirmed.
|
||||
* `confirmed`: The balance of all funds in confirmed transactions.
|
||||
* `total`: The total of funds owned (ie, `confirmed + unconfirmed`)
|
||||
* `immature`: The total unspendable funds (ie, coinbase reward which need 100 confirmations before being spendable)
|
||||
* `available`: The total spendable balance. (ie, `total - immature`)
|
||||
|
||||
Immature funds is the sum of UTXO's belonging to a coinbase transaction with less than 100 confirmations.
|
||||
|
||||
## <a name="gettransaction"></a>Get a transaction
|
||||
|
||||
HTTP GET v1/cryptos/{cryptoCode}/transactions/{txId}
|
||||
@ -470,7 +485,7 @@ Returns:
|
||||
}
|
||||
```
|
||||
|
||||
## <a name="utxos"></a>Get Unspent Transaction Outputs (UTXOs)
|
||||
## <a name="utxos"></a>Get available Unspent Transaction Outputs (UTXOs)
|
||||
|
||||
HTTP GET v1/cryptos/{cryptoCode}/derivations/{derivationScheme}/utxos
|
||||
|
||||
@ -526,8 +541,9 @@ Result:
|
||||
```
|
||||
|
||||
This call does not returns conflicted unconfirmed UTXOs.
|
||||
Note that confirmed utxo, do not include immature UTXOs. (ie. UTXOs belonging to a coinbase transaction with less than 100 confirmations)
|
||||
|
||||
## <a name="address-utxos"></a>Get Unspent Transaction Outputs of a specific address
|
||||
## <a name="address-utxos"></a>Get available Unspent Transaction Outputs of a specific address
|
||||
|
||||
Assuming you use Track on this specific address:
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user