diff --git a/README.md b/README.md
index 58210d2..978012c 100644
--- a/README.md
+++ b/README.md
@@ -87,7 +87,7 @@ In addition to static vs dynamic typing, C# and Python have very different conve
 - Parameter names are `camelCased`.
 - The chia RPC uses unsigned integers where dotnet might use signed. In cases where chia expects an unsigned number, it is unsigned on the dotnet side.
 - `ulong` is used for the python 64 bit unsigned int.
-- `BigInteger` is used for the python 128 bit unsigned int.
+- `System.UInt128` is used for the python 128 bit unsigned int.
 - Where the RPC return a scalar value, the dotnet code will as well. If it is optional in python it will be `Nullable<T>` in dotnet
 - Where the RPC returns a list of named scalar values, they are returned as a Tuple with named fields.
 - Lists of things are returned as [`IEnumberable<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1?view=net-5.0).
diff --git a/src/chia-dotnet.tests/chia-dotnet.tests.csproj b/src/chia-dotnet.tests/chia-dotnet.tests.csproj
index 2e6d9ee..88f43c5 100644
--- a/src/chia-dotnet.tests/chia-dotnet.tests.csproj
+++ b/src/chia-dotnet.tests/chia-dotnet.tests.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
     <PropertyGroup>
-        <TargetFramework>net7.0</TargetFramework>
+        <TargetFramework>net8.0</TargetFramework>
         <IsPackable>false</IsPackable>
         <RootNamespace>chia.dotnet.tests</RootNamespace>
         <UserSecretsId>chia.dotnet.tests</UserSecretsId>
diff --git a/src/chia-dotnet/CATWallet.cs b/src/chia-dotnet/CATWallet.cs
index e89b4dd..176590d 100644
--- a/src/chia-dotnet/CATWallet.cs
+++ b/src/chia-dotnet/CATWallet.cs
@@ -9,17 +9,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a CAT wallet
     /// </summary>
-    public sealed class CATWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class CATWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public CATWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.CAT"/>
diff --git a/src/chia-dotnet/CRCATWallet.cs b/src/chia-dotnet/CRCATWallet.cs
index 4bde132..8fb0208 100644
--- a/src/chia-dotnet/CRCATWallet.cs
+++ b/src/chia-dotnet/CRCATWallet.cs
@@ -7,17 +7,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a CRCAT  Wallet
     /// </summary>
-    public sealed class CRCATWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class CRCATWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public CRCATWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.CRCAT"/>
diff --git a/src/chia-dotnet/ChiaTypes/Announcement.cs b/src/chia-dotnet/ChiaTypes/Announcement.cs
index 91fe0a4..e7b4c02 100644
--- a/src/chia-dotnet/ChiaTypes/Announcement.cs
+++ b/src/chia-dotnet/ChiaTypes/Announcement.cs
@@ -4,6 +4,6 @@ public record Announcement
     {
         public string OriginInfo { get; init; } = string.Empty;
         public string Message { get; init; } = string.Empty;
-        public string MorphBytes { get; init; } = string.Empty;
+        public string? MorphBytes { get; init; }
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/AutoClaimSettings.cs b/src/chia-dotnet/ChiaTypes/AutoClaimSettings.cs
index f9aecf0..0d16b82 100644
--- a/src/chia-dotnet/ChiaTypes/AutoClaimSettings.cs
+++ b/src/chia-dotnet/ChiaTypes/AutoClaimSettings.cs
@@ -5,6 +5,6 @@ public record AutoClaimSettings
         public bool Enabled { get; init; }
         public ulong TxFee { get; init; }
         public ulong MinAmount { get; init; }
-        public ushort BatchSize { get; init; }
+        public ushort BatchSize { get; init; } = 50;
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/BlockRecord.cs b/src/chia-dotnet/ChiaTypes/BlockRecord.cs
index f808916..dbfaa2d 100644
--- a/src/chia-dotnet/ChiaTypes/BlockRecord.cs
+++ b/src/chia-dotnet/ChiaTypes/BlockRecord.cs
@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Numerics;
 
 using Newtonsoft.Json;
 
@@ -91,11 +90,11 @@ public record BlockRecord
         /// <summary>
         /// Total number of VDF iterations since genesis, including this block
         /// </summary>
-        public BigInteger TotalIters { get; init; }
+        public UInt128 TotalIters { get; init; }
         /// <summary>
         /// Total cumulative difficulty of all ancestor blocks since genesis
         /// </summary>
-        public BigInteger Weight { get; init; }
+        public UInt128 Weight { get; init; }
         [JsonIgnore]
         public DateTime? DateTimestamp => Timestamp.ToDateTime();
         [JsonIgnore]
diff --git a/src/chia-dotnet/ChiaTypes/BlockSpendWithConditions.cs b/src/chia-dotnet/ChiaTypes/BlockSpendWithConditions.cs
index a813367..5b15e7d 100644
--- a/src/chia-dotnet/ChiaTypes/BlockSpendWithConditions.cs
+++ b/src/chia-dotnet/ChiaTypes/BlockSpendWithConditions.cs
@@ -5,6 +5,6 @@ namespace chia.dotnet
     public record BlockSpendWithConditions
     {
         public CoinSpend CoinSpend { get; init; } = new();
-        public IEnumerable<ConditionWithArgs> Conditions { get; init; } = new List<ConditionWithArgs>();
+        public IEnumerable<ConditionWithVars> Conditions { get; init; } = new List<ConditionWithVars>();
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/BlockchainState.cs b/src/chia-dotnet/ChiaTypes/BlockchainState.cs
index 15848fc..730ecb9 100644
--- a/src/chia-dotnet/ChiaTypes/BlockchainState.cs
+++ b/src/chia-dotnet/ChiaTypes/BlockchainState.cs
@@ -1,6 +1,4 @@
-using System.Numerics;
-
-namespace chia.dotnet
+namespace chia.dotnet
 {
     /// <summary>
     /// The node's view of the blockchain.
@@ -17,7 +15,7 @@ public record BlockchainState
         public long MempoolMaxTotalCost { get; init; }
         public long BlockMaxCost { get; init; }
         public BlockRecord? Peak { get; init; }
-        public BigInteger Space { get; init; }
+        public System.UInt128 Space { get; init; }
         public ulong SubSlotIters { get; init; }
         public SyncState Sync { get; init; } = new();
         public uint AverageBlockTime { get; init; }
diff --git a/src/chia-dotnet/ChiaTypes/Coin.cs b/src/chia-dotnet/ChiaTypes/Coin.cs
index 9a04af8..addc122 100644
--- a/src/chia-dotnet/ChiaTypes/Coin.cs
+++ b/src/chia-dotnet/ChiaTypes/Coin.cs
@@ -10,7 +10,7 @@ public record Coin
     {
         public string ParentCoinInfo { get; init; } = string.Empty;
         public string PuzzleHash { get; init; } = string.Empty;
-        public ulong Amount { get; init; }
+        public System.UInt128 Amount { get; init; }
 
         /// <summary>
         /// The <see cref="Amount"/> as a hex string
diff --git a/src/chia-dotnet/ChiaTypes/CoinAnnouncement.cs b/src/chia-dotnet/ChiaTypes/CoinAnnouncement.cs
index 8515a99..d3a644a 100644
--- a/src/chia-dotnet/ChiaTypes/CoinAnnouncement.cs
+++ b/src/chia-dotnet/ChiaTypes/CoinAnnouncement.cs
@@ -4,6 +4,6 @@ public record CoinAnnouncement
     {
         public string CoinId { get; init; } = string.Empty;
         public string Message { get; init; } = string.Empty;
-        public string MorphBytes { get; init; } = string.Empty;
+        public string? MorphBytes { get; init; }
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/Condition.cs b/src/chia-dotnet/ChiaTypes/Condition.cs
index 8860dc7..e5885c4 100644
--- a/src/chia-dotnet/ChiaTypes/Condition.cs
+++ b/src/chia-dotnet/ChiaTypes/Condition.cs
@@ -14,6 +14,6 @@ namespace chia.dotnet
     public record Condition
     {
         public string ConditionOpcode { get; init; } = string.Empty;
-        public IEnumerable<ConditionWithArgs> Args { get; init; } = new List<ConditionWithArgs>();
+        public IEnumerable<ConditionWithVars> Args { get; init; } = new List<ConditionWithVars>();
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/ConditionConverter.cs b/src/chia-dotnet/ChiaTypes/ConditionConverter.cs
index 2563e9c..36d41ab 100644
--- a/src/chia-dotnet/ChiaTypes/ConditionConverter.cs
+++ b/src/chia-dotnet/ChiaTypes/ConditionConverter.cs
@@ -16,13 +16,13 @@ internal sealed class ConditionConverter : JsonConverter<Condition>
 
             var opcode = reader.ReadAsString(); // the opcode is stored without a name (as part of an unnamed tuple (aka array in json))
             _ = reader.Read(); // move ahead to the start of the collection
-            var args = serializer.Deserialize<IEnumerable<ConditionWithArgs>>(reader);
+            var args = serializer.Deserialize<IEnumerable<ConditionWithVars>>(reader);
             _ = reader.Read();
 
             return new Condition()
             {
                 ConditionOpcode = opcode ?? string.Empty,
-                Args = args ?? new List<ConditionWithArgs>()
+                Args = args ?? new List<ConditionWithVars>()
             };
         }
 
diff --git a/src/chia-dotnet/ChiaTypes/ConditionValidTimes.cs b/src/chia-dotnet/ChiaTypes/ConditionValidTimes.cs
new file mode 100644
index 0000000..559fc9d
--- /dev/null
+++ b/src/chia-dotnet/ChiaTypes/ConditionValidTimes.cs
@@ -0,0 +1,14 @@
+namespace chia.dotnet
+{
+    public record ConditionValidTimes
+    {
+        public ulong? MinSecsSinceCreated { get; init; }
+        public ulong? MinTime { get; init; }
+        public ulong? MinBlocksSinceCreated { get; init; }
+        public uint? MinHeight { get; init; }
+        public ulong? MaxSecAfterCreated { get; init; }
+        public ulong? MaxTime { get; init; }
+        public uint? MaxBlocksAfterCreated { get; init; }
+        public uint? MaxHeight { get; init; }
+    }
+}
diff --git a/src/chia-dotnet/ChiaTypes/ConditionWithArgs.cs b/src/chia-dotnet/ChiaTypes/ConditionWithVars.cs
similarity index 91%
rename from src/chia-dotnet/ChiaTypes/ConditionWithArgs.cs
rename to src/chia-dotnet/ChiaTypes/ConditionWithVars.cs
index 7d02fa6..9113838 100644
--- a/src/chia-dotnet/ChiaTypes/ConditionWithArgs.cs
+++ b/src/chia-dotnet/ChiaTypes/ConditionWithVars.cs
@@ -6,7 +6,7 @@ namespace chia.dotnet
     /// This structure is used to store parsed CLVM conditions
     /// Conditions in CLVM have either format of(opcode, var1) or(opcode, var1, var2)
     /// </summary>
-    public record ConditionWithArgs
+    public record ConditionWithVars
     {
         public ushort Opcode { get; init; }
         public IEnumerable<string> Vars { get; init; } = new List<string>();
diff --git a/src/chia-dotnet/ChiaTypes/PuzzleAnnouncement.cs b/src/chia-dotnet/ChiaTypes/PuzzleAnnouncement.cs
index eec1d74..c9c53a9 100644
--- a/src/chia-dotnet/ChiaTypes/PuzzleAnnouncement.cs
+++ b/src/chia-dotnet/ChiaTypes/PuzzleAnnouncement.cs
@@ -4,6 +4,6 @@ public record PuzzleAnnouncement
     {
         public string PuzzleHash { get; init; } = string.Empty;
         public string Message { get; init; } = string.Empty;
-        public string MorphBytes { get; init; } = string.Empty;
+        public string? MorphBytes { get; init; }
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/RewardChainBlock.cs b/src/chia-dotnet/ChiaTypes/RewardChainBlock.cs
index 2cfe1a1..4efd561 100644
--- a/src/chia-dotnet/ChiaTypes/RewardChainBlock.cs
+++ b/src/chia-dotnet/ChiaTypes/RewardChainBlock.cs
@@ -1,12 +1,10 @@
-using System.Numerics;
-
-namespace chia.dotnet
+namespace chia.dotnet
 {
     public record RewardChainBlock
     {
-        public BigInteger Weight { get; init; }
+        public System.UInt128 Weight { get; init; }
         public uint Height { get; init; }
-        public BigInteger TotalIters { get; init; }
+        public System.UInt128 TotalIters { get; init; }
         public byte SignagePointIndex { get; init; }
         public string PosSsCcChallengeHash { get; init; } = string.Empty;
         public ProofOfSpace ProofOfSpace { get; init; } = new();
diff --git a/src/chia-dotnet/ChiaTypes/RewardChainBlockUnfinished.cs b/src/chia-dotnet/ChiaTypes/RewardChainBlockUnfinished.cs
index cce22bc..160086e 100644
--- a/src/chia-dotnet/ChiaTypes/RewardChainBlockUnfinished.cs
+++ b/src/chia-dotnet/ChiaTypes/RewardChainBlockUnfinished.cs
@@ -1,10 +1,8 @@
-using System.Numerics;
-
-namespace chia.dotnet
+namespace chia.dotnet
 {
     public record RewardChainBlockUnfinished
     {
-        public BigInteger TotalIters { get; init; }
+        public System.UInt128 TotalIters { get; init; }
         public byte SignagePointIndex { get; init; }
         public string PosSsCcChallengeHash { get; init; } = string.Empty;
         public ProofOfSpace ProofOfSpace { get; init; } = new();
diff --git a/src/chia-dotnet/ChiaTypes/TransactionRecord.cs b/src/chia-dotnet/ChiaTypes/TransactionRecord.cs
index 188b459..ad3f022 100644
--- a/src/chia-dotnet/ChiaTypes/TransactionRecord.cs
+++ b/src/chia-dotnet/ChiaTypes/TransactionRecord.cs
@@ -46,5 +46,6 @@ public record TransactionRecord
         public uint WalletId { get; init; }
         [JsonIgnore]
         public DateTime CreatedAtDateTime => CreatedAtTime.ToDateTime();
+        public ConditionValidTimes ValidTimes { get; init; } = new();
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/TransactionTypeFilter.cs b/src/chia-dotnet/ChiaTypes/TransactionTypeFilter.cs
index 849624b..e777b08 100644
--- a/src/chia-dotnet/ChiaTypes/TransactionTypeFilter.cs
+++ b/src/chia-dotnet/ChiaTypes/TransactionTypeFilter.cs
@@ -1,10 +1,11 @@
-namespace chia.dotnet
+using System.Collections.Generic;
+
+namespace chia.dotnet
 {
     public record TransactionTypeFilter
     {
-        public string AssetId { get; init; } = string.Empty;
-        public string Name { get; init; } = string.Empty;
-        public uint FirstSeenHeight { get; init; }
-        public string SenderPuzzleHash { get; init; } = string.Empty;
+        public IEnumerable<byte> Values { get; init; } = new List<byte>();
+
+        public FilterMode Mode { get; init; } = FilterMode.Exlude;
     }
 }
diff --git a/src/chia-dotnet/ChiaTypes/WalletBalance.cs b/src/chia-dotnet/ChiaTypes/WalletBalance.cs
index a808c7a..17e353b 100644
--- a/src/chia-dotnet/ChiaTypes/WalletBalance.cs
+++ b/src/chia-dotnet/ChiaTypes/WalletBalance.cs
@@ -2,11 +2,11 @@
 {
     public record WalletBalance
     {
-        public ulong ConfirmedWalletBalance { get; init; }
-        public ulong UnconfirmedWalletBalance { get; init; }
-        public ulong SpendableBalance { get; init; }
-        public ulong PendingChange { get; init; }
-        public ulong MaxSendAmount { get; init; }
+        public System.UInt128 ConfirmedWalletBalance { get; init; }
+        public System.UInt128 UnconfirmedWalletBalance { get; init; }
+        public System.UInt128 SpendableBalance { get; init; }
+        public System.UInt128 PendingChange { get; init; }
+        public System.UInt128 MaxSendAmount { get; init; }
         public int UnspentCoinCount { get; init; }
         public int PendingCoinRemovalCount { get; init; }
         public WalletType WalletType { get; init; }
diff --git a/src/chia-dotnet/CrawlerProxy.cs b/src/chia-dotnet/CrawlerProxy.cs
index 15af2ca..814f787 100644
--- a/src/chia-dotnet/CrawlerProxy.cs
+++ b/src/chia-dotnet/CrawlerProxy.cs
@@ -9,17 +9,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the crawler
     /// </summary>
-    public sealed class CrawlerProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class CrawlerProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Crawler, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public CrawlerProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Crawler, originService)
-        {
-        }
 
         /// <summary>
         /// Retrieves aggregate information about peers
diff --git a/src/chia-dotnet/DAOWallet.cs b/src/chia-dotnet/DAOWallet.cs
index 2f90d6d..933b1df 100644
--- a/src/chia-dotnet/DAOWallet.cs
+++ b/src/chia-dotnet/DAOWallet.cs
@@ -7,17 +7,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a DAO Wallet
     /// </summary>
-    public sealed class DAOWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class DAOWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public DAOWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.DAO"/>
@@ -106,7 +102,7 @@ public async Task<IDictionary<string, object>> ParseProposal(string proposalId,
         /// </summary>
         /// <param name="cancellationToken">A token to allow the call to be cancelled</param>
         /// <returns></returns>
-        public async Task<IDictionary<string, ulong>> GetTreasuryBalance(CancellationToken cancellationToken = default)
+        public async Task<IDictionary<string, System.UInt128>> GetTreasuryBalance(CancellationToken cancellationToken = default)
         {
             dynamic data = CreateWalletDataObject();
             return await WalletProxy.SendMessage<IDictionary<string, ulong>>("dao_get_treasury_balance", data, cancellationToken).ConfigureAwait(false);
diff --git a/src/chia-dotnet/DIDWallet.cs b/src/chia-dotnet/DIDWallet.cs
index 5ec5a4d..02b7f10 100644
--- a/src/chia-dotnet/DIDWallet.cs
+++ b/src/chia-dotnet/DIDWallet.cs
@@ -9,17 +9,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a Distributed Identity Wallet
     /// </summary>
-    public sealed class DIDWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class DIDWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public DIDWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.DISTRIBUTED_ID"/>
@@ -40,10 +36,7 @@ public override async Task Validate(CancellationToken cancellationToken = defaul
         /// <returns>An awaitable <see cref="Task"/></returns>
         public async Task UpdateRecoveryIds(IEnumerable<string> newList, ulong? numVerificationsRequired = null, bool? reusePuzhash = null, CancellationToken cancellationToken = default)
         {
-            if (newList is null)
-            {
-                throw new ArgumentNullException(nameof(newList));
-            }
+            ArgumentNullException.ThrowIfNull(newList);
 
             dynamic data = CreateWalletDataObject();
             data.new_list = newList.ToList();
@@ -62,10 +55,7 @@ public async Task UpdateRecoveryIds(IEnumerable<string> newList, ulong? numVerif
         /// <returns>An awaitable <see cref="Task"/></returns>
         public async Task UpdateRecoveryIds(IEnumerable<string> newList, ulong numVerificationsRequired, CancellationToken cancellationToken = default)
         {
-            if (newList is null)
-            {
-                throw new ArgumentNullException(nameof(newList));
-            }
+            ArgumentNullException.ThrowIfNull(newList);
 
             dynamic data = CreateWalletDataObject();
             data.new_list = newList.ToList();
@@ -212,10 +202,7 @@ public async Task<SpendBundle> UpdateMetadata(string metadata, bool? reusePuzhas
         /// <returns>An awaitable <see cref="Task"/></returns>
         public async Task RecoverySpend(IEnumerable<string> attestData, string? pubkey, string? puzzlehash, CancellationToken cancellationToken = default)
         {
-            if (attestData is null)
-            {
-                throw new ArgumentNullException(nameof(attestData));
-            }
+            ArgumentNullException.ThrowIfNull(attestData);
 
             dynamic data = CreateWalletDataObject();
             data.attest_data = attestData.ToList();
diff --git a/src/chia-dotnet/DaemonProxy.cs b/src/chia-dotnet/DaemonProxy.cs
index 24d63dc..95ca505 100644
--- a/src/chia-dotnet/DaemonProxy.cs
+++ b/src/chia-dotnet/DaemonProxy.cs
@@ -12,17 +12,13 @@ namespace chia.dotnet
     /// The daemon can be used to proxy messages to and from other chia services as well
     /// as controlling the <see cref="PlotterProxy"/> and having it's own procedures
     /// </summary>
-    public sealed class DaemonProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class DaemonProxy(WebSocketRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Daemon, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public DaemonProxy(WebSocketRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Daemon, originService)
-        {
-        }
 
         /// <summary>
         /// Sends ping message to the service
@@ -42,7 +38,7 @@ public async Task Ping(CancellationToken cancellationToken = default)
         /// <remarks>This only works for daemons because they can forward messages to other services through their <see cref="WebSocketRpcClient"/></remarks>
         public T CreateProxyFrom<T>() where T : ServiceProxy
         {
-            var constructor = typeof(T).GetConstructor(new Type[] { typeof(IRpcClient), typeof(string) });
+            var constructor = typeof(T).GetConstructor([typeof(IRpcClient), typeof(string)]);
             return constructor is null || constructor.Invoke(new object[] { RpcClient, OriginService }) is not T proxy
                 ? throw new InvalidOperationException($"Cannot create a {typeof(T).Name}")
                 : proxy;
diff --git a/src/chia-dotnet/DataLayerProxy.cs b/src/chia-dotnet/DataLayerProxy.cs
index b1ce9bc..4482982 100644
--- a/src/chia-dotnet/DataLayerProxy.cs
+++ b/src/chia-dotnet/DataLayerProxy.cs
@@ -10,17 +10,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the Data Layer
     /// </summary>
-    public sealed class DataLayerProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class DataLayerProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.DataLayer, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public DataLayerProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.DataLayer, originService)
-        {
-        }
 
         /// <summary>
         /// Adds a mirror
diff --git a/src/chia-dotnet/DataLayerWallet.cs b/src/chia-dotnet/DataLayerWallet.cs
index ba3afc4..cb64b9f 100644
--- a/src/chia-dotnet/DataLayerWallet.cs
+++ b/src/chia-dotnet/DataLayerWallet.cs
@@ -9,17 +9,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a Data Layer Wallet
     /// </summary>
-    public sealed class DataLayerWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class DataLayerWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public DataLayerWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.DATA_LAYER"/>
diff --git a/src/chia-dotnet/Extensions.cs b/src/chia-dotnet/Extensions.cs
index 231b23f..11f50e0 100644
--- a/src/chia-dotnet/Extensions.cs
+++ b/src/chia-dotnet/Extensions.cs
@@ -86,7 +86,7 @@ public static string AsChia(this ulong mojo, string? format, IFormatProvider? pr
         /// <remarks>Adapted from https://stackoverflow.com/questions/281640/how-do-i-get-a-human-readable-file-size-in-bytes-abbreviation-using-net </remarks>
         public static string ToBytesString(this BigInteger byteCount, string format = "N3")
         {
-            string[] suffixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB" };
+            string[] suffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB"];
             if (byteCount.IsZero)
             {
                 return $"{0.0.ToString(format)} {suffixes[0]}";
@@ -104,6 +104,33 @@ public static string ToBytesString(this BigInteger byteCount, string format = "N
             return $"{num.ToString(format)} {suffixes[place]}";
         }
 
+        /// <summary>
+        /// Format a number of bytes in human readable format 
+        /// </summary>
+        /// <param name="byteCount">The number of bytes</param>
+        /// <param name="format">Return string culture format</param>
+        /// <returns>A human readable string</returns>
+        /// <remarks>Adapted from https://stackoverflow.com/questions/281640/how-do-i-get-a-human-readable-file-size-in-bytes-abbreviation-using-net </remarks>
+        public static string ToBytesString(this UInt128 byteCount, string format = "N3")
+        {
+            string[] suffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB"];
+            if (byteCount == 0)
+            {
+                return $"{0.0.ToString(format)} {suffixes[0]}";
+            }
+
+            var abs = BigInteger.Abs(byteCount); // in case byteCount is negative
+            var place = Convert.ToInt32(Math.Floor(BigInteger.Log(abs, 1024)));
+            var pow = Math.Pow(1024, place);
+
+            // since we need to do this with integer math, get the quotient and remainder
+            var quotient = BigInteger.DivRem(abs, new BigInteger(pow), out var remainder);
+            // convert the remainder to a ratio and add both back together as doubles, putting the sign back
+            var num = UInt128.Sign(byteCount) * (Math.Floor((double)quotient) + ((double)remainder / pow));
+
+            return $"{num.ToString(format)} {suffixes[place]}";
+        }
+
         /// <summary>
         /// Format a number of bytes in human readable format 
         /// </summary>
@@ -113,7 +140,7 @@ public static string ToBytesString(this BigInteger byteCount, string format = "N
         /// <remarks>Adapted from https://stackoverflow.com/questions/281640/how-do-i-get-a-human-readable-file-size-in-bytes-abbreviation-using-net </remarks>
         public static string ToBytesString(this ulong byteCount, string format = "N3")
         {
-            string[] suffixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB" };
+            string[] suffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB"];
             if (byteCount == 0)
             {
                 return $"{0.0.ToString(format)} {suffixes[0]}";
@@ -176,7 +203,7 @@ public static string ToBytesString(this long byteCount, string format = "N3")
         /// <returns>A human readable string</returns>
         public static string ToBytesString(this double byteCount, string format = "N3")
         {
-            string[] suffixes = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB" };
+            string[] suffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB"];
             if (byteCount == 0)
             {
                 return $"{0.0.ToString(format)} {suffixes[0]}";
diff --git a/src/chia-dotnet/FarmerProxy.cs b/src/chia-dotnet/FarmerProxy.cs
index f44aad2..a994844 100644
--- a/src/chia-dotnet/FarmerProxy.cs
+++ b/src/chia-dotnet/FarmerProxy.cs
@@ -10,17 +10,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the farmer
     /// </summary>
-    public sealed class FarmerProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class FarmerProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Farmer, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public FarmerProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Farmer, originService)
-        {
-        }
 
         /// <summary>
         /// Get the farm and pool reward targets 
@@ -56,7 +52,7 @@ public FarmerProxy(IRpcClient rpcClient, string originService)
         /// <returns>The farm and pool reward targets</returns>
         public async Task<(string FarmerTarget, string PoolTarget, bool HaveFarmerSk, bool HavePoolSk)> GetRewardTargetsIncludingPrivateKey(CancellationToken cancellationToken = default)
         {
-            return await GetRewardTargetsIncludingPrivateKey(cancellationToken: cancellationToken).ConfigureAwait(false);
+            return await GetRewardTargetsIncludingPrivateKey(500, cancellationToken: cancellationToken).ConfigureAwait(false);
         }
 
         /// <summary>
diff --git a/src/chia-dotnet/FullNodeProxy.cs b/src/chia-dotnet/FullNodeProxy.cs
index 247132a..c8d94a2 100644
--- a/src/chia-dotnet/FullNodeProxy.cs
+++ b/src/chia-dotnet/FullNodeProxy.cs
@@ -2,7 +2,6 @@
 using System.Collections.Generic;
 using System.Dynamic;
 using System.Linq;
-using System.Numerics;
 using System.Threading;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
@@ -12,17 +11,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the full node
     /// </summary>
-    public sealed class FullNodeProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class FullNodeProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.FullNode, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public FullNodeProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.FullNode, originService)
-        {
-        }
 
         /// <summary>
         /// Will wait until <see cref="GetBlockchainState(CancellationToken)"/> indicates 
@@ -290,10 +285,7 @@ public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByPuzzleHash(string puz
         /// <returns>A list of <see cref="CoinRecord"/>s</returns>
         public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByNames(IEnumerable<string> names, bool includeSpentCoins, uint? startHeight = null, uint? endHeight = null, CancellationToken cancellationToken = default)
         {
-            if (names is null)
-            {
-                throw new ArgumentNullException(nameof(names));
-            }
+            ArgumentNullException.ThrowIfNull(names);
 
             dynamic data = new ExpandoObject();
             data.names = names.ToList();
@@ -315,10 +307,7 @@ public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByNames(IEnumerable<str
         /// <returns>A list of <see cref="CoinRecord"/>s</returns>
         public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByPuzzleHashes(IEnumerable<string> puzzlehashes, bool includeSpentCoins, uint? startHeight = null, uint? endHeight = null, CancellationToken cancellationToken = default)
         {
-            if (puzzlehashes is null)
-            {
-                throw new ArgumentNullException(nameof(puzzlehashes));
-            }
+            ArgumentNullException.ThrowIfNull(puzzlehashes);
 
             dynamic data = new ExpandoObject();
             data.puzzle_hashes = puzzlehashes.ToList();
@@ -341,10 +330,7 @@ public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByPuzzleHashes(IEnumera
         /// <returns>A list of <see cref="CoinRecord"/>s</returns>
         public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByParentIds(IEnumerable<string> parentIds, bool includeSpentCoins, uint? startHeight = null, uint? endHeight = null, CancellationToken cancellationToken = default)
         {
-            if (parentIds is null)
-            {
-                throw new ArgumentNullException(nameof(parentIds));
-            }
+            ArgumentNullException.ThrowIfNull(parentIds);
 
             dynamic data = new ExpandoObject();
             data.parent_ids = parentIds.ToList();
@@ -492,8 +478,8 @@ public async Task<IEnumerable<MempoolItem>> GetMemmpoolItemsByCoinName(string co
         /// <param name="newerBlockHeaderhash"></param>
         /// <param name="olderBlockHeaderhash"></param>
         /// <param name="cancellationToken">A token to allow the call to be cancelled</param>
-        /// <returns><see cref="BigInteger"/> of network space in bytes</returns>
-        public async Task<BigInteger> GetNetworkSpace(string newerBlockHeaderhash, string olderBlockHeaderhash, CancellationToken cancellationToken = default)
+        /// <returns><see cref="UInt128"/> of network space in bytes</returns>
+        public async Task<UInt128> GetNetworkSpace(string newerBlockHeaderhash, string olderBlockHeaderhash, CancellationToken cancellationToken = default)
         {
             if (string.IsNullOrEmpty(newerBlockHeaderhash))
             {
@@ -535,10 +521,7 @@ public async Task<BigInteger> GetNetworkSpace(string newerBlockHeaderhash, strin
         /// <returns>Indicator of whether the spend bundle was successfully included in the mempool</returns>
         public async Task<bool> PushTx(SpendBundle spendBundle, CancellationToken cancellationToken = default)
         {
-            if (spendBundle is null)
-            {
-                throw new ArgumentNullException(nameof(spendBundle));
-            }
+            ArgumentNullException.ThrowIfNull(spendBundle);
 
             dynamic data = new ExpandoObject();
             data.spend_bundle = spendBundle;
diff --git a/src/chia-dotnet/HarvesterProxy.cs b/src/chia-dotnet/HarvesterProxy.cs
index 0f119db..c770249 100644
--- a/src/chia-dotnet/HarvesterProxy.cs
+++ b/src/chia-dotnet/HarvesterProxy.cs
@@ -9,17 +9,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the harvester
     /// </summary>
-    public sealed class HarvesterProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class HarvesterProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Harvester, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public HarvesterProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Harvester, originService)
-        {
-        }
 
         /// <summary>
         /// Gets harvester configuration.
diff --git a/src/chia-dotnet/NFTWallet.cs b/src/chia-dotnet/NFTWallet.cs
index 5a20dde..3ab9a91 100644
--- a/src/chia-dotnet/NFTWallet.cs
+++ b/src/chia-dotnet/NFTWallet.cs
@@ -8,17 +8,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps an NFT wallet
     /// </summary>
-    public sealed class NFTWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class NFTWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public NFTWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.NFT"/>
diff --git a/src/chia-dotnet/PlotterProxy.cs b/src/chia-dotnet/PlotterProxy.cs
index f11d1cc..3fc3ab1 100644
--- a/src/chia-dotnet/PlotterProxy.cs
+++ b/src/chia-dotnet/PlotterProxy.cs
@@ -10,18 +10,14 @@ namespace chia.dotnet
     /// <summary>
     /// Class to manage plotting
     /// </summary>
-    public sealed class PlotterProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    /// <remarks>The daemon endpoint handles plotting commands, so the rpc client has to us a websocket client and dameon endpoint</remarks>
+    public sealed class PlotterProxy(WebSocketRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Daemon, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        /// <remarks>The daemon endpoint handles plotting commands, so the rpc client has to us a websocket client and dameon endpoint</remarks>
-        public PlotterProxy(WebSocketRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Daemon, originService)
-        {
-        }
 
         /// <summary>
         /// Registers this instance as a plotter and retreives the plot queue
@@ -44,10 +40,7 @@ public async Task<IEnumerable<QueuedPlotInfo>> RegisterPlotter(CancellationToken
         /// <returns>An awaitable <see cref="Task"/></returns>
         public async Task<IEnumerable<string>> StartPlotting(PlotterConfig config, CancellationToken cancellationToken = default)
         {
-            if (config == null)
-            {
-                throw new ArgumentNullException(nameof(config));
-            }
+            ArgumentNullException.ThrowIfNull(config);
 
             dynamic data = config.PrepareForSerialization();
             return await SendMessage<IEnumerable<string>>("start_plotting", data, "ids", cancellationToken).ConfigureAwait(false);
diff --git a/src/chia-dotnet/PoolWallet.cs b/src/chia-dotnet/PoolWallet.cs
index 9cd87b6..0135f4d 100644
--- a/src/chia-dotnet/PoolWallet.cs
+++ b/src/chia-dotnet/PoolWallet.cs
@@ -8,17 +8,13 @@ namespace chia.dotnet
     /// <summary>
     /// Wraps a Pool Wallet
     /// </summary>
-    public sealed class PoolWallet : Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public sealed class PoolWallet(uint walletId, WalletProxy walletProxy) : Wallet(walletId, walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public PoolWallet(uint walletId, WalletProxy walletProxy)
-            : base(walletId, walletProxy)
-        {
-        }
 
         /// <summary>
         /// Validates that <see cref="Wallet.WalletId"/> is a <see cref="WalletType.POOLING_WALLET"/>
diff --git a/src/chia-dotnet/ResponseException.cs b/src/chia-dotnet/ResponseException.cs
index e6cba38..693c66a 100644
--- a/src/chia-dotnet/ResponseException.cs
+++ b/src/chia-dotnet/ResponseException.cs
@@ -6,7 +6,13 @@ namespace chia.dotnet
     /// Exception thrown when the RPC endpoint returns a response <see cref="Message"/> but Data.success is false
     /// oro there is a communication error on the websocket of http channgel
     /// </summary>
-    public sealed class ResponseException : Exception
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="request">The request sent to the service</param>
+    /// <param name="message"><see cref="Exception.Message"/></param>
+    /// <param name="innerException"><see cref="Exception.InnerException"/></param>
+    public sealed class ResponseException(Message request, string message, Exception? innerException) : Exception(message, innerException)
     {
         /// <summary>
         /// ctor
@@ -27,21 +33,9 @@ public ResponseException(Message request, string message)
         {
         }
 
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="request">The request sent to the service</param>
-        /// <param name="message"><see cref="Exception.Message"/></param>
-        /// <param name="innerException"><see cref="Exception.InnerException"/></param>
-        public ResponseException(Message request, string message, Exception? innerException)
-            : base(message, innerException)
-        {
-            Request = request;
-        }
-
         /// <summary>
         /// The request sent to the service
         /// </summary>
-        public Message Request { get; init; }
+        public Message Request { get; init; } = request;
     }
 }
diff --git a/src/chia-dotnet/TradeManager.cs b/src/chia-dotnet/TradeManager.cs
index 5413741..c48393d 100644
--- a/src/chia-dotnet/TradeManager.cs
+++ b/src/chia-dotnet/TradeManager.cs
@@ -10,14 +10,9 @@ namespace chia.dotnet
     /// <summary>
     /// API wrapper for those wallet RPC methods dealing with trades and offers
     /// </summary>
-    public sealed class TradeManager
+    public sealed class TradeManager(WalletProxy walletProxy)
     {
-        public WalletProxy WalletProxy { get; init; }
-
-        public TradeManager(WalletProxy walletProxy)
-        {
-            WalletProxy = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
-        }
+        public WalletProxy WalletProxy { get; init; } = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
 
         /// <summary>
         /// Retrieves the number of offers.
@@ -271,10 +266,7 @@ public async Task<OfferSummary> GetOfferSummary(string offer, bool advanced = fa
         /// <returns>An awaitable <see cref="Task"/></returns>
         public async Task<OfferRecord> CreateOffer(IDictionary<uint, long> walletIdsAndMojoAmounts, ulong minCoinAmount = 0, ulong maxCoinAmount = 0, bool validateOnly = false, IDictionary<string, string>? driver = null, IDictionary<string, string>? solver = null, bool? reusePuzhash = null, ulong fee = 0, CancellationToken cancellationToken = default)
         {
-            if (walletIdsAndMojoAmounts is null)
-            {
-                throw new ArgumentNullException(nameof(walletIdsAndMojoAmounts));
-            }
+            ArgumentNullException.ThrowIfNull(walletIdsAndMojoAmounts);
 
             dynamic data = new ExpandoObject();
             data.offer = walletIdsAndMojoAmounts;
diff --git a/src/chia-dotnet/VerifiedCredentialManager.cs b/src/chia-dotnet/VerifiedCredentialManager.cs
index 6024b83..ce52d86 100644
--- a/src/chia-dotnet/VerifiedCredentialManager.cs
+++ b/src/chia-dotnet/VerifiedCredentialManager.cs
@@ -9,14 +9,9 @@ namespace chia.dotnet
     /// <summary>
     /// API wrapper for those wallet RPC methods dealing with verified credentials
     /// </summary>
-    public sealed class VerifiedCredentialManager
+    public sealed class VerifiedCredentialManager(WalletProxy walletProxy)
     {
-        public WalletProxy WalletProxy { get; init; }
-
-        public VerifiedCredentialManager(WalletProxy walletProxy)
-        {
-            WalletProxy = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
-        }
+        public WalletProxy WalletProxy { get; init; } = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
 
         /// <summary>
         /// Given a launcher ID get the verified credential.
diff --git a/src/chia-dotnet/Wallet.cs b/src/chia-dotnet/Wallet.cs
index 1842288..3c8deea 100644
--- a/src/chia-dotnet/Wallet.cs
+++ b/src/chia-dotnet/Wallet.cs
@@ -11,28 +11,23 @@ namespace chia.dotnet
     /// Base class representing a specific wallet (i.e. anything with a WalletID)
     /// </summary>
     /// <remarks>When not dervied from this represents a <see cref="WalletType.STANDARD_WALLET"/></remarks>
-    public class Wallet
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="walletId">The wallet_id to wrap</param>
+    /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
+    public class Wallet(uint walletId, WalletProxy walletProxy)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="walletId">The wallet_id to wrap</param>
-        /// <param name="walletProxy">Wallet RPC proxy to use for communication</param>
-        public Wallet(uint walletId, WalletProxy walletProxy)
-        {
-            WalletId = walletId;
-            WalletProxy = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
-        }
 
         /// <summary>
         /// The id of the wallet
         /// </summary>
-        public uint WalletId { get; init; }
+        public uint WalletId { get; init; } = walletId;
 
         /// <summary>
         /// Wallet RPC proxy for communication
         /// </summary>
-        public WalletProxy WalletProxy { get; init; }
+        public WalletProxy WalletProxy { get; init; } = walletProxy ?? throw new ArgumentNullException(nameof(walletProxy));
 
         /// <summary>
         /// Creates a dynamic object and sets its wallet_id property to <see cref="WalletId"/>
@@ -294,10 +289,7 @@ public async Task<TransactionRecord> SendTransaction(string address,
         /// <returns>The <see cref="TransactionRecord"/></returns>
         public async Task<TransactionRecord> SendTransactionMulti(IEnumerable<Coin> additions, IEnumerable<Coin>? coins = null, ulong fee = 0, CancellationToken cancellationToken = default)
         {
-            if (additions is null)
-            {
-                throw new ArgumentNullException(nameof(additions));
-            }
+            ArgumentNullException.ThrowIfNull(additions);
 
             dynamic data = CreateWalletDataObject();
             data.additions = additions.ToList();
diff --git a/src/chia-dotnet/WalletProxy.cs b/src/chia-dotnet/WalletProxy.cs
index f62ff97..677fe24 100644
--- a/src/chia-dotnet/WalletProxy.cs
+++ b/src/chia-dotnet/WalletProxy.cs
@@ -11,17 +11,13 @@ namespace chia.dotnet
     /// <summary>
     /// Proxy that communicates with the wallet endpoint
     /// </summary>
-    public sealed class WalletProxy : ServiceProxy
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
+    /// <param name="originService"><see cref="Message.Origin"/></param>
+    public sealed class WalletProxy(IRpcClient rpcClient, string originService) : ServiceProxy(rpcClient, ServiceNames.Wallet, originService)
     {
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="rpcClient"><see cref="IRpcClient"/> instance to use for rpc communication</param>
-        /// <param name="originService"><see cref="Message.Origin"/></param>
-        public WalletProxy(IRpcClient rpcClient, string originService)
-            : base(rpcClient, ServiceNames.Wallet, originService)
-        {
-        }
 
         /// <summary>
         /// Gets basic info about a pool that is used for pool wallet creation
@@ -240,10 +236,7 @@ public async Task<TransactionRecord> GetTransaction(string transactionId, Cancel
         /// <returns>Indicator of whether the spend bundle was successfully included in the mempool</returns>
         public async Task<bool> PushTx(SpendBundle spendBundle, CancellationToken cancellationToken = default)
         {
-            if (spendBundle is null)
-            {
-                throw new ArgumentNullException(nameof(spendBundle));
-            }
+            ArgumentNullException.ThrowIfNull(spendBundle);
 
             dynamic data = new ExpandoObject();
             data.spend_bundle = spendBundle;
@@ -261,10 +254,7 @@ public async Task<bool> PushTx(SpendBundle spendBundle, CancellationToken cancel
         /// <returns>An awaitable task</returns>
         public async Task PushTransactions(IEnumerable<TransactionRecord> transactions, CancellationToken cancellationToken = default)
         {
-            if (transactions is null)
-            {
-                throw new ArgumentNullException(nameof(transactions));
-            }
+            ArgumentNullException.ThrowIfNull(transactions);
 
             dynamic data = new ExpandoObject();
             data.transactions = transactions.ToList();
@@ -280,10 +270,7 @@ public async Task PushTransactions(IEnumerable<TransactionRecord> transactions,
         /// <returns>The new key's fingerprint</returns>
         public async Task<uint> AddKey(IEnumerable<string> mnemonic, CancellationToken cancellationToken = default)
         {
-            if (mnemonic is null)
-            {
-                throw new ArgumentNullException(nameof(mnemonic));
-            }
+            ArgumentNullException.ThrowIfNull(mnemonic);
 
             dynamic data = new ExpandoObject();
             data.mnemonic = mnemonic.ToList();
@@ -505,10 +492,7 @@ public async Task<NFTInfo> GetNFTInfo(string coinId, bool latest = true, bool ig
         /// <returns>Information about the wallet</returns>
         public async Task<(WalletType Type, string myDID, uint walletId)> CreateDIDWallet(IEnumerable<string> backupDIDs, ulong numOfBackupIdsNeeded, string name, IDictionary<string, string>? metaData = null, ulong fee = 0, CancellationToken cancellationToken = default)
         {
-            if (backupDIDs is null)
-            {
-                throw new ArgumentNullException(nameof(backupDIDs));
-            }
+            ArgumentNullException.ThrowIfNull(backupDIDs);
 
             dynamic data = new ExpandoObject();
             data.wallet_type = "did_wallet";
@@ -585,10 +569,7 @@ public async Task<NFTInfo> GetNFTInfo(string coinId, bool latest = true, bool ig
         public async Task<(TransactionRecord transaction, string launcherId, string p2SingletonHash)>
             CreatePoolWallet(PoolState initialTargetState, ulong? p2SingletonDelayTime = null, string? p2SingletonDelayedPH = null, CancellationToken cancellationToken = default)
         {
-            if (initialTargetState is null)
-            {
-                throw new ArgumentNullException(nameof(initialTargetState));
-            }
+            ArgumentNullException.ThrowIfNull(initialTargetState);
 
             dynamic data = new ExpandoObject();
             data.wallet_type = "pool_wallet";
@@ -657,10 +638,7 @@ public async Task<NFTInfo> GetNFTInfo(string coinId, bool latest = true, bool ig
             ulong fee = 0,
             CancellationToken cancellationToken = default)
         {
-            if (additions is null)
-            {
-                throw new ArgumentNullException(nameof(additions));
-            }
+            ArgumentNullException.ThrowIfNull(additions);
 
             dynamic data = new ExpandoObject();
             data.additions = additions.ToList();
@@ -695,19 +673,6 @@ public async Task<NFTInfo> GetNFTInfo(string coinId, bool latest = true, bool ig
                 );
         }
 
-        /// <summary>
-        /// Create but do not send a transaction
-        /// </summary>
-        /// <param name="additions">Additions to the block chain</param>
-        /// <param name="fee">Fee amount (in units of mojos)</param>
-        /// <param name="cancellationToken">A token to allow the call to be cancelled</param>
-        /// <returns>The signed <see cref="TransactionRecord"/></returns>
-        public async Task<TransactionRecord> CreateSignedTransaction(IEnumerable<Coin> additions, ulong fee = 0, CancellationToken cancellationToken = default)
-        {
-            return await CreateSignedTransaction(additions, fee: fee, cancellationToken).ConfigureAwait(false);
-        }
-
-
         /// <summary>
         /// Retrieves the coins for given coin IDs
         /// </summary>
@@ -719,10 +684,7 @@ public async Task<TransactionRecord> CreateSignedTransaction(IEnumerable<Coin> a
         /// <returns>A list of <see cref="CoinRecord"/>s</returns>
         public async Task<IEnumerable<CoinRecord>> GetCoinRecordsByNames(IEnumerable<string> names, bool includeSpentCoins, uint? startHeight = null, uint? endHeight = null, CancellationToken cancellationToken = default)
         {
-            if (names is null)
-            {
-                throw new ArgumentNullException(nameof(names));
-            }
+            ArgumentNullException.ThrowIfNull(names);
 
             dynamic data = new ExpandoObject();
             data.names = names.ToList();
diff --git a/src/chia-dotnet/bech32/Bech32M.cs b/src/chia-dotnet/bech32/Bech32M.cs
index 13be724..ee93aae 100644
--- a/src/chia-dotnet/bech32/Bech32M.cs
+++ b/src/chia-dotnet/bech32/Bech32M.cs
@@ -12,25 +12,20 @@ namespace chia.dotnet.bech32
     /// Bech32M implementation for encoding addresses
     /// </summary>
     /// <remarks>adapted from https://github.com/Playwo/ChiaRPC.Net/blob/master/ChiaRPC.Net/Utils/Bech32M.cs</remarks>
-    public class Bech32M
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="prefix">Address prefix</param>
+    public class Bech32M(string prefix = "xch")
     {
         /// <summary>
         /// Address prefix to use
         /// </summary>
         /// <value>xch</value>
-        public string AddressPrefix { get; init; } = "xch";
+        public string AddressPrefix { get; init; } = prefix;
         private const string Charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
         private const int M = 0x2BC830A3;
-        private static readonly int[] Generator = new int[] { 0x3B6A57B2, 0x26508E6D, 0x1EA119FA, 0x3D4233DD, 0x2A1462B3 };
-
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="prefix">Address prefix</param>
-        public Bech32M(string prefix = "xch")
-        {
-            AddressPrefix = prefix;
-        }
+        private static readonly int[] Generator = [0x3B6A57B2, 0x26508E6D, 0x1EA119FA, 0x3D4233DD, 0x2A1462B3];
 
         /// <summary>
         /// Converts a puzzle hash to an address using <see cref="AddressPrefix"/>
@@ -199,7 +194,7 @@ private static string Encode(string hrp, List<int> data)
         /// <returns></returns>
         private static (string?, List<int>?) Decode(string bech)
         {
-            if (bech.ToLower() != bech && bech.ToUpper() != bech)
+            if (!bech.Equals(bech, StringComparison.OrdinalIgnoreCase) && !bech.Equals(bech, StringComparison.OrdinalIgnoreCase))
             {
                 return (null, null);
             }
@@ -213,7 +208,7 @@ private static (string?, List<int>?) Decode(string bech)
             }
 
             bech = bech.ToLower();
-            var lastOnePosition = bech.LastIndexOf("1");
+            var lastOnePosition = bech.LastIndexOf('1');
 
             if (lastOnePosition < 1 || lastOnePosition + 7 > bech.Length || bech.Length > 90)
             {
diff --git a/src/chia-dotnet/bech32/HexBytes.cs b/src/chia-dotnet/bech32/HexBytes.cs
index e38ae1b..d6df6ab 100644
--- a/src/chia-dotnet/bech32/HexBytes.cs
+++ b/src/chia-dotnet/bech32/HexBytes.cs
@@ -8,34 +8,28 @@ namespace chia.dotnet.bech32
     /// Utility to perform operations on an array of bytes and represent them as a Hex string
     /// </summary>
     /// <remarks>adapted from https://github.com/Playwo/ChiaRPC.Net/blob/master/ChiaRPC.Net/Utils/Bech32M.cs</remarks>
-    public readonly struct HexBytes
+    /// <remarks>
+    /// ctor
+    /// </remarks>
+    /// <param name="hex"></param>
+    /// <param name="bytes"></param>
+    public readonly struct HexBytes(string hex, byte[] bytes)
     {
         /// <summary>
         /// <see cref="Bytes"/> hex string representation
         /// </summary>
-        public string Hex { get; init; }
+        public string Hex { get; init; } = hex ?? string.Empty;
 
         /// <summary>
         /// The array of bytes
         /// </summary>
-        public byte[] Bytes { get; init; }
+        public byte[] Bytes { get; init; } = bytes ?? [];
 
         /// <summary>
         /// FLag indicating that the array is empty
         /// </summary>
         public bool IsEmpty => string.IsNullOrWhiteSpace(Hex);
 
-        /// <summary>
-        /// ctor
-        /// </summary>
-        /// <param name="hex"></param>
-        /// <param name="bytes"></param>
-        public HexBytes(string hex, byte[] bytes)
-        {
-            Hex = hex ?? string.Empty;
-            Bytes = bytes ?? Array.Empty<byte>();
-        }
-
         /// <summary>
         /// SHA256 encoded copy 
         /// </summary>
@@ -50,7 +44,7 @@ public HexBytes Sha256()
 
         public override bool Equals(object? obj)
         {
-            return obj is HexBytes other && Hex.ToUpperInvariant() == other.Hex.ToUpperInvariant();
+            return obj is HexBytes other && Hex.Equals(other.Hex, StringComparison.OrdinalIgnoreCase);
         }
 
         public override int GetHashCode()
@@ -91,12 +85,12 @@ public override string ToString()
 
         public static bool operator ==(HexBytes a, HexBytes b)
         {
-            return a.Hex.ToUpperInvariant() == b.Hex.ToUpperInvariant();
+            return a.Hex.Equals(b.Hex, StringComparison.OrdinalIgnoreCase);
         }
 
         public static bool operator !=(HexBytes a, HexBytes b)
         {
-            return a.Hex.ToUpperInvariant() != b.Hex.ToUpperInvariant();
+            return !a.Hex.Equals(b.Hex, StringComparison.OrdinalIgnoreCase);
         }
 
         public static HexBytes FromHex(string hex)
@@ -136,6 +130,6 @@ public static HexBytes FromBytes(byte[] bytes)
         /// <summary>
         /// 
         /// </summary>
-        public static HexBytes Empty => new(string.Empty, Array.Empty<byte>());
+        public static HexBytes Empty => new(string.Empty, []);
     }
 }
diff --git a/src/chia-dotnet/chia-dotnet.csproj b/src/chia-dotnet/chia-dotnet.csproj
index a34775c..5e31e69 100644
--- a/src/chia-dotnet/chia-dotnet.csproj
+++ b/src/chia-dotnet/chia-dotnet.csproj
@@ -1,13 +1,13 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <RootNamespace>chia.dotnet</RootNamespace>
     <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <Version>2.2.1</Version>
+    <Version>3.0.0</Version>
     <Authors>dkackman</Authors>
     <Company>dkackman</Company>
     <Description>A .net client library for chia™ RPC interfaces that runs on linux and windows.</Description>
@@ -18,11 +18,12 @@
     <RepositoryUrl>https://github.com/dkackman/chia-dotnet</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <PackageTags>chia, 2.1.2</PackageTags>
-    <PackageReleaseNotes>Add Dao Wallet</PackageReleaseNotes>
+    <PackageReleaseNotes>.NET 8
+UInt 128</PackageReleaseNotes>
     <PackageIcon>chia-leaf-logo-384x384.png</PackageIcon>
     <PackageIconUrl />
-    <AssemblyVersion>2.2.1.0</AssemblyVersion>
-    <FileVersion>2.2.1.0</FileVersion>
+    <AssemblyVersion>3.0.0.0</AssemblyVersion>
+    <FileVersion>3.0.0.0</FileVersion>
     <Nullable>enable</Nullable>
     <Title>chia.dotnet</Title>
     <PackageReadmeFile>README.md</PackageReadmeFile>
diff --git a/src/docfx/docfx.csproj b/src/docfx/docfx.csproj
index d351ec5..cbb58ed 100644
--- a/src/docfx/docfx.csproj
+++ b/src/docfx/docfx.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
   </PropertyGroup>