From fc4f2580f17eab881ff3546544d0c76252a7b619 Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Tue, 14 Nov 2023 18:03:06 +0000
Subject: [PATCH 1/6] use relative time locks for penalties

---
 src/Angor.Test/InvestmentOperationsTest.cs    |  6 +++---
 src/Angor.Test/ProtocolNew/AngorTestData.cs   |  2 +-
 .../InvestmentIntegrationsTests.cs            | 10 +++++-----
 .../SeederTransactionActionsTest.cs           |  6 +++---
 .../InvestmentTransactionBuilderTest.cs       | 10 +++++-----
 src/Angor.Test/ScriptThresholdTest.cs         |  1 +
 src/Angor.Test/WalletOperationsTest.cs        |  2 +-
 src/Angor/Client/NetworkConfiguration.cs      |  6 +++---
 .../Client/Pages/CheckTransactionCode.razor   |  4 ++--
 src/Angor/Client/Pages/Create.razor           |  8 ++++----
 src/Angor/Client/Pages/Invest.razor           |  2 +-
 src/Angor/Client/Pages/Penalties.razor        | 12 ++++++++++--
 src/Angor/Client/Pages/Recover.razor          | 10 ++++++----
 src/Angor/Client/Pages/View.razor             |  2 +-
 src/Angor/Shared/Models/ProjectInfo.cs        |  2 +-
 .../Shared/Protocol/InvestmentOperations.cs   |  2 +-
 .../Shared/{ => Protocol}/ScriptBuilder.cs    | 19 ++++++++++---------
 .../ProtocolNew/ISeederTransactionActions.cs  |  2 +-
 .../ProtocolNew/InvestorTransactionActions.cs | 14 ++++++++------
 .../Scripts/IInvestmentScriptbuilder.cs       |  2 +-
 .../Scripts/InvestmentScriptBuilder.cs        | 14 +++++++++-----
 .../ProtocolNew/SeederTransactionActions.cs   |  6 +++---
 .../IInvestmentTransactionBuilder.cs          |  2 +-
 .../InvestmentTransactionBuilder.cs           |  4 ++--
 24 files changed, 83 insertions(+), 65 deletions(-)
 rename src/Angor/Shared/{ => Protocol}/ScriptBuilder.cs (94%)

diff --git a/src/Angor.Test/InvestmentOperationsTest.cs b/src/Angor.Test/InvestmentOperationsTest.cs
index 7d047d2f..c3f8ef5d 100644
--- a/src/Angor.Test/InvestmentOperationsTest.cs
+++ b/src/Angor.Test/InvestmentOperationsTest.cs
@@ -419,7 +419,7 @@ public void SpendInvestorRecoveryTest()
                     FounderKey = funderKey,
                     FounderRecoveryKey = funderRecoveryKey,
                     ProjectIdentifier = angorKey,
-                    PenaltyDate = DateTime.UtcNow.AddDays(5),
+                    PenaltyDays = 5,
                     ProjectSeeders = new ProjectSeeders()
                 },
                 InvestorKey = Encoders.Hex.EncodeData(investorKey.PubKey.ToBytes()),
@@ -519,7 +519,7 @@ public void SpendInvestorConsolidatedRecoveryTest()
                         FounderKey = funderKey,
                         FounderRecoveryKey = funderRecoveryKey,
                         ProjectIdentifier = angorKey,
-                        PenaltyDate = DateTime.UtcNow.AddDays(5),
+                        PenaltyDays = 5,
                         ProjectSeeders = new ProjectSeeders
                         {
                             Threshold = 2,
@@ -632,7 +632,7 @@ public void SpendSeederConsolidatedRecoveryTest()
                         FounderKey = funderKey,
                         FounderRecoveryKey = funderRecoveryKey,
                         ProjectIdentifier = angorKey,
-                        PenaltyDate = DateTime.UtcNow.AddDays(5),
+                        PenaltyDays = 5,
                         ProjectSeeders = new ProjectSeeders()
                     },
                     InvestorKey = Encoders.Hex.EncodeData(seederKey.PubKey.ToBytes()),
diff --git a/src/Angor.Test/ProtocolNew/AngorTestData.cs b/src/Angor.Test/ProtocolNew/AngorTestData.cs
index aa1b6bf0..487ab99e 100644
--- a/src/Angor.Test/ProtocolNew/AngorTestData.cs
+++ b/src/Angor.Test/ProtocolNew/AngorTestData.cs
@@ -35,7 +35,7 @@ protected ProjectInfo GivenValidProjectInvestmentInfo( WalletWords? words = null
         projectInvestmentInfo.TargetAmount = 3;
         projectInvestmentInfo.StartDate = startDate.Value;
         projectInvestmentInfo.ExpiryDate = startDate.Value.AddDays(5);
-        projectInvestmentInfo.PenaltyDate = startDate.Value.AddDays(10);
+        projectInvestmentInfo.PenaltyDays = 10;
         projectInvestmentInfo.Stages = new List<Stage>
         {
             new() { AmountToRelease = (decimal)0.1, ReleaseDate = startDate.Value.AddDays(1) },
diff --git a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
index 7f5ea9a7..7ee3fa90 100644
--- a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
+++ b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
@@ -258,8 +258,8 @@ public void SeederTransaction_EndOfProject_Test()
             projectInvestmentInfo.FounderRecoveryKey = _derivationOperations.DeriveFounderRecoveryKey(words, 1);
             projectInvestmentInfo.ProjectIdentifier =
                 _derivationOperations.DeriveAngorKey(projectInvestmentInfo.FounderKey, angorRootKey);
-            
-            projectInvestmentInfo.PenaltyDate = DateTime.Now.AddMonths(6);
+
+            projectInvestmentInfo.PenaltyDays = 180;
 
             // Create the seeder 1 params
             var seeder11Key = new Key();
@@ -433,7 +433,7 @@ public void SpendSeederRecoveryTest()
                     FounderKey = funderKey,
                     FounderRecoveryKey = founderRecoveryKey,
                     ProjectIdentifier = angorKey,
-                    PenaltyDate = DateTime.UtcNow.AddDays(5),
+                    PenaltyDays = 5,
                     ProjectSeeders = new ProjectSeeders()
                 },
                 InvestorKey = Encoders.Hex.EncodeData(seederKey.PubKey.ToBytes()),
@@ -449,7 +449,7 @@ public void SpendSeederRecoveryTest()
 
             var recoveryTransaction = _seederTransactionActions.BuildRecoverSeederFundsTransaction(investorContext.ProjectInfo, 
                 investmentTransaction,
-                investorContext.ProjectInfo.PenaltyDate, Encoders.Hex.EncodeData(seederFundsRecoveryKey.PubKey.ToBytes()));
+                investorContext.ProjectInfo.PenaltyDays, Encoders.Hex.EncodeData(seederFundsRecoveryKey.PubKey.ToBytes()));
 
             var founderSignatures = _founderTransactionActions.SignInvestorRecoveryTransactions(investorContext.ProjectInfo,
                 investmentTransaction.ToHex(),recoveryTransaction,
@@ -493,7 +493,7 @@ public void SpendInvestorRecoveryTest()
                     TargetAmount = 3,
                     StartDate = DateTime.UtcNow,
                     ExpiryDate = DateTime.UtcNow.AddDays(5),
-                    PenaltyDate = DateTime.UtcNow.AddDays(5),
+                    PenaltyDays = 5,
                     Stages = new List<Stage>
                     {
                         new() { AmountToRelease = 1, ReleaseDate = DateTime.UtcNow.AddDays(1) },
diff --git a/src/Angor.Test/ProtocolNew/SeederTransactionActionsTest.cs b/src/Angor.Test/ProtocolNew/SeederTransactionActionsTest.cs
index aeb30c1b..8dc7ed34 100644
--- a/src/Angor.Test/ProtocolNew/SeederTransactionActionsTest.cs
+++ b/src/Angor.Test/ProtocolNew/SeederTransactionActionsTest.cs
@@ -105,14 +105,14 @@ public void BuildRecoverSeederFundsTransactions_CallsBuildUpfrontRecoverFundsTra
         var investmentTrxHex = "010000000102df7eb0603e53da8760b6037cca974550e85489d36d59efcedb8834bb691a71000000006a473044022047870ec27da9e51c3f4657b6ac376bb240191b93b1c597775f092a3c6e20e66602203f544e972f45e796730c02942393f9b7d02b4d6dc2301281c68029e693194549012103d418fd52b6bd5fc9330c51aa4480aa9f3bba2940bedc7ce7535ac164aebc25efffffffff06c0c62d0000000000160014b81698f9e2e78fa7fc87f8009183c8a4ab25a6c70000000000000000446a2103eb7d47c80390672435987b9a7ecaa22730cd9c4537fc8d257417fb058248ed7720fcdcd57c6c65b40bcdf9b454a96891d7375a60d516e3416af61f86d4999d44e180c3c901000000002251204f3edc853deba516c82aa9479daaddbe5c34bdde1b2a7be369d784e560271123804a5d0500000000225120d2f4094dc5c80bee991b76b089f230f086edfcef20550467026f80e79647b3f900879303000000002251208ea1c42515559fd53f811b333be518484aeecf9409aefeccb8e977b43ae1d9c99c547e6d00000000160014333a905154f56ef18b6f7aee53ed45a231da54f700000000";
         
         var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);
-        var penaltyDate = DateTime.Now.AddMonths(6);
+        var penaltyDays = 180;
         var receiveAddress = Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes());
         var newProject = new ProjectInfo();
 
-        var recoveryTransactions = _sut.BuildRecoverSeederFundsTransaction(newProject, investmentTrx, penaltyDate, 
+        var recoveryTransactions = _sut.BuildRecoverSeederFundsTransaction(newProject, investmentTrx, penaltyDays, 
             receiveAddress);
         
-        _investmentTransactionBuilder.Verify(_ => _.BuildUpfrontRecoverFundsTransaction(newProject, investmentTrx,penaltyDate,receiveAddress),
+        _investmentTransactionBuilder.Verify(_ => _.BuildUpfrontRecoverFundsTransaction(newProject, investmentTrx,penaltyDays,receiveAddress),
             Times.Once);
     }
 }
\ No newline at end of file
diff --git a/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs b/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
index 6275dd36..a03d9ba9 100644
--- a/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
+++ b/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
@@ -117,10 +117,10 @@ public void BuildRecoverSeederFundsTransactions_AllTransactionsReturnedWithStage
         
         var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);
 
-        _investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(It.IsAny<string>(), It.IsAny<DateTime>()))
+        _investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(It.IsAny<string>(), It.IsAny<int>()))
             .Returns(new Key().ScriptPubKey);
 
-        var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx, DateTime.Now.AddMonths(6),
+        var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx, 180,
             Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes()));
 
         //All inputs are from the investment transaction outputs
@@ -137,14 +137,14 @@ public void BuildRecoverSeederFundsTransactions_AllTransactionsReturnedWithTheRi
         var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);
 
         var expectedAddress = Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes());
-        var expectedDateTime = DateTime.Now.AddMonths(6);
+        var expectedDays = 180;
         var expectedScript = new Key().ScriptPubKey;
         
-        _investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(expectedAddress, expectedDateTime))
+        _investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(expectedAddress, expectedDays))
             .Returns(expectedScript);
 
         var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx, 
-            expectedDateTime, expectedAddress);
+            expectedDays, expectedAddress);
         
         //All outputs pay to the penalty script
         Assert.Contains(recoveryTransaction.Outputs,
diff --git a/src/Angor.Test/ScriptThresholdTest.cs b/src/Angor.Test/ScriptThresholdTest.cs
index 3ef8f4bc..3b613049 100644
--- a/src/Angor.Test/ScriptThresholdTest.cs
+++ b/src/Angor.Test/ScriptThresholdTest.cs
@@ -1,4 +1,5 @@
 using Angor.Shared;
+using Angor.Shared.Protocol;
 
 namespace Angor.Test
 {
diff --git a/src/Angor.Test/WalletOperationsTest.cs b/src/Angor.Test/WalletOperationsTest.cs
index 98743bd2..50acb5ef 100644
--- a/src/Angor.Test/WalletOperationsTest.cs
+++ b/src/Angor.Test/WalletOperationsTest.cs
@@ -150,7 +150,7 @@ public void AddInputsAndSignTransaction()
         projectInfo.TargetAmount = 3;
         projectInfo.StartDate = DateTime.UtcNow;
         projectInfo.ExpiryDate = DateTime.UtcNow.AddDays(5);
-        projectInfo.PenaltyDate= DateTime.UtcNow.AddDays(10);
+        projectInfo.PenaltyDays= 10;
         projectInfo.Stages = new List<Stage>
         {
             new Stage { AmountToRelease = 1, ReleaseDate = DateTime.UtcNow.AddDays(1) },
diff --git a/src/Angor/Client/NetworkConfiguration.cs b/src/Angor/Client/NetworkConfiguration.cs
index 81a22783..8bfd133c 100644
--- a/src/Angor/Client/NetworkConfiguration.cs
+++ b/src/Angor/Client/NetworkConfiguration.cs
@@ -59,7 +59,7 @@ public static List<ProjectInfo> CreateFakeProjects()
                 new ProjectInfo
                 {
                     StartDate = DateTime.UtcNow,
-                    PenaltyDate = DateTime.UtcNow,
+                    PenaltyDays = 100,
                     ExpiryDate = DateTime.UtcNow,
                     TargetAmount = 300,
                     ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
@@ -73,7 +73,7 @@ public static List<ProjectInfo> CreateFakeProjects()
                 new ProjectInfo
                 {
                     StartDate = DateTime.UtcNow,
-                    PenaltyDate = DateTime.UtcNow,
+                    PenaltyDays = 100,
                     ExpiryDate = DateTime.UtcNow,
                     TargetAmount = 200,
                     ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
@@ -87,7 +87,7 @@ public static List<ProjectInfo> CreateFakeProjects()
                 new ProjectInfo
                 {
                     StartDate = DateTime.UtcNow,
-                    PenaltyDate = DateTime.UtcNow,
+                    PenaltyDays = 100,
                     ExpiryDate = DateTime.UtcNow,
                     TargetAmount = 100,
                     ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
diff --git a/src/Angor/Client/Pages/CheckTransactionCode.razor b/src/Angor/Client/Pages/CheckTransactionCode.razor
index 5b0f8279..60c150bc 100644
--- a/src/Angor/Client/Pages/CheckTransactionCode.razor
+++ b/src/Angor/Client/Pages/CheckTransactionCode.razor
@@ -159,7 +159,7 @@ else
                 },
                 ExpiryDate = DateTime.Now.AddDays(1),
                 FounderKey = Encoders.Hex.EncodeData(privateFounderKey.Neuter().PubKey.ToBytes()),
-                PenaltyDate = DateTime.Now.AddMinutes(1000),
+                PenaltyDays = 100,
                 StartDate = DateTime.Now,
                 TargetAmount = 10,
                 ProjectIdentifier = derivationOperations.DeriveAngorKey(Encoders.Hex.EncodeData(privateFounderKey.Neuter().PubKey.ToBytes()),angorRootKey),
@@ -172,7 +172,7 @@ else
 
         context.TransactionHex = transaction.ToHex();
 
-        recoveryTransaction = SeederTransactionActions.BuildRecoverSeederFundsTransaction(context.ProjectInfo, transaction, context.ProjectInfo.PenaltyDate, testAddress.PubKey.ToHex());
+        recoveryTransaction = SeederTransactionActions.BuildRecoverSeederFundsTransaction(context.ProjectInfo, transaction, context.ProjectInfo.PenaltyDays, testAddress.PubKey.ToHex());
 
         var signatures = FounderTransactionActions.SignInvestorRecoveryTransactions(context.ProjectInfo, context.TransactionHex, recoveryTransaction, Encoders.Hex.EncodeData(privateFounderKey.PrivateKey.ToBytes()));
 
diff --git a/src/Angor/Client/Pages/Create.razor b/src/Angor/Client/Pages/Create.razor
index 38d7e34f..772e025f 100644
--- a/src/Angor/Client/Pages/Create.razor
+++ b/src/Angor/Client/Pages/Create.razor
@@ -55,8 +55,8 @@
 
         <!-- Penalty Date -->
         <div class="mb-3">
-            <label for="penaltyDate" class="form-label">Penalty Date</label>
-            <InputDate id="penaltyDate" @bind-Value="project.PenaltyDate" class="form-control"/>
+            <label for="penaltyDate" class="form-label">Penalty Days</label>
+            <InputNumber id="penaltyDate" @bind-Value="project.PenaltyDays" class="form-control" />
         </div>
 
         <!-- Expiry Date -->
@@ -110,7 +110,7 @@
 
                         <p class="mb-1"><strong>Start date:</strong> @project.StartDate.ToString("dd/MM/yyyy") in @((project.StartDate - DateTime.Now).Days) days</p>
                         <p class="mb-1"><strong>Expiry date:</strong> @project.ExpiryDate.ToString("dd/MM/yyyy") in @((project.ExpiryDate - DateTime.Now).Days) days</p>
-                        <p class="mb-1"><strong>Penalty date:</strong> @project.PenaltyDate.ToString("dd/MM/yyyy") in @((project.PenaltyDate - DateTime.Now).Days) days</p>
+                        <p class="mb-1"><strong>Penalty days:</strong> @project.PenaltyDays days</p>
 
                         <p class="mb-1"><strong>Miner fee:</strong> [Your fee here]</p>
                         <p class="mb-1"><strong>Angor fee:</strong> 1000 sats</p>
@@ -163,7 +163,7 @@
     private ProjectInfo project = new ProjectInfo
     {
         StartDate = DateTime.UtcNow,
-        PenaltyDate = DateTime.UtcNow.AddDays(100),
+        PenaltyDays = 100,
         ExpiryDate = DateTime.UtcNow.AddDays(50),
         TargetAmount = 100,
         TransactionId = "unknowen",
diff --git a/src/Angor/Client/Pages/Invest.razor b/src/Angor/Client/Pages/Invest.razor
index e1fe7128..3c6ea5b1 100644
--- a/src/Angor/Client/Pages/Invest.razor
+++ b/src/Angor/Client/Pages/Invest.razor
@@ -102,7 +102,7 @@
 
                         <p class="mb-1"><strong>Start date:</strong> @project.StartDate.ToString("dd/MM/yyyy") in @((project.StartDate - DateTime.Now).Days) days</p>
                         <p class="mb-1"><strong>Expiry date:</strong> @project.ExpiryDate.ToString("dd/MM/yyyy") in @((project.ExpiryDate - DateTime.Now).Days) days</p>
-                        <p class="mb-1"><strong>Penalty date:</strong> @project.PenaltyDate.ToString("dd/MM/yyyy") in @((project.PenaltyDate - DateTime.Now).Days) days</p>
+                        <p class="mb-1"><strong>Penalty days:</strong> @project.PenaltyDays days</p>
 
                         <p class="mb-1"><strong>Miner fee:</strong> [Your fee here]</p>
                         <p class="mb-1"><strong>Angor fee:</strong> 1000 sats</p>
diff --git a/src/Angor/Client/Pages/Penalties.razor b/src/Angor/Client/Pages/Penalties.razor
index cf91614f..1a8010f3 100644
--- a/src/Angor/Client/Pages/Penalties.razor
+++ b/src/Angor/Client/Pages/Penalties.razor
@@ -110,8 +110,8 @@
                     {
                         ProjectIdentifier = signatureInfo.ProjectIdentifier,
                         RecoveryTransactionId = signatureInfo.RecoveryTransactionId,
-                        DaysLeftForPenalty = (project.PenaltyDate - DateTime.Now).Days,
-                        IsExpired = (project.PenaltyDate - DateTime.Now).Days <= 0,
+                        //DaysLeftForPenalty = (project.PenaltyDays - DateTime.Now).Days,
+                        //IsExpired = (project.PenaltyDays - DateTime.Now).Days <= 0,
                         IsReleased = !string.IsNullOrEmpty(signatureInfo.RecoveryReleaseTransactionId),
                     });
                 }
@@ -127,12 +127,20 @@
             {
                 var operationResult = await notificationComponent.LongOperation(async () =>
                 {
+                    var projects = storage.GetProjects();
+
                     foreach (var penaltyProject in penaltyProjects)
                     {
                         var recoveryTansaction = await _IndexerService.GetTransactionInfoByIdAsync(penaltyProject.RecoveryTransactionId);
                         
                         var totalsats = recoveryTansaction.Outputs.Where(s => Script.FromHex(s.ScriptPubKey).IsScriptType(ScriptType.P2WSH)).Sum(s => s.Balance);
                         penaltyProject.Amount = Money.Satoshis(totalsats).ToUnit(MoneyUnit.BTC);
+
+                        var project = projects.First(p => p.ProjectIdentifier == penaltyProject.ProjectIdentifier);
+
+                        var expieryDate = Utils.UnixTimeToDateTime(recoveryTansaction.Timestamp).AddDays(project.PenaltyDays);
+                        penaltyProject.DaysLeftForPenalty = (expieryDate - DateTimeOffset.UtcNow).Days;
+                        penaltyProject.IsExpired = (expieryDate - DateTimeOffset.UtcNow).Days <= 0;
                     }
 
                     return new OperationResult { Success = true };
diff --git a/src/Angor/Client/Pages/Recover.razor b/src/Angor/Client/Pages/Recover.razor
index 7aa311db..94def214 100644
--- a/src/Angor/Client/Pages/Recover.razor
+++ b/src/Angor/Client/Pages/Recover.razor
@@ -106,7 +106,7 @@
 
                         <p class="mb-1">The amount to be recovered in to a penalty = @StageInfo.Items.Where(s=> !s.IsSpent).Sum(s=> s.Amount) BTC</p>
 
-                        <p class="mb-1">The penalty duration is @((project.PenaltyDate - DateTime.UtcNow).Days) days </p>
+                        <p class="mb-1">The penalty duration is @project.PenaltyDays days </p>
                         
                         <hr>
 
@@ -323,6 +323,8 @@
 
     private async Task CheckSpentFund()
     {
+        var penaltyExpieryDate = Utils.UnixTimeToDateTime(StageInfo.TransactionInfo.Timestamp).AddDays(project.PenaltyDays);
+
         foreach (var item in StageInfo.Items)
         {
             var output = StageInfo.TransactionInfo.Outputs.ElementAt(item.Outputindex);
@@ -341,7 +343,7 @@
                     else
                     {
                         item.ProjectScriptType = new ProjectScriptType { ScriptType = ProjectScriptTypeEnum.InvestorWithPenalty };
-                        var days = (project.PenaltyDate - DateTime.Now).Days;
+                        var days = (penaltyExpieryDate - DateTime.Now).Days;
                         item.SpentTo = days > 0 ? $"Penalty, released in {days} days" : "Penalty can be released";
                     }
                 }
@@ -365,7 +367,7 @@
                             }
                             case ProjectScriptTypeEnum.InvestorWithPenalty:
                             {
-                                var days = (project.PenaltyDate - DateTime.Now).Days;
+                                var days = (penaltyExpieryDate - DateTime.Now).Days;
                                 item.SpentTo = days > 0 ? $"Penalty, released in {days} days" : "Penalty can be released";
                                 break;
                             }
@@ -383,7 +385,7 @@
 
         StageInfo.CanRecover = StageInfo.Items.Any(a => a.IsSpent == false);
         StageInfo.TotalSpendable = StageInfo.Items.Where(a => !a.IsSpent).Sum(a => a.Amount);
-        StageInfo.CanRelease = (StageInfo.Items.Any(a => a.ProjectScriptType?.ScriptType == ProjectScriptTypeEnum.InvestorWithPenalty) && DateTime.UtcNow > project.PenaltyDate);
+        StageInfo.CanRelease = (StageInfo.Items.Any(a => a.ProjectScriptType?.ScriptType == ProjectScriptTypeEnum.InvestorWithPenalty) && DateTime.UtcNow > penaltyExpieryDate);
         StageInfo.TotalInPenalty = StageInfo.Items.Where(t => t.ProjectScriptType?.ScriptType == ProjectScriptTypeEnum.InvestorWithPenalty).Sum(t => t.Amount);
         StageInfo.EndOfProject = project.ExpiryDate < DateTime.Now;
     }
diff --git a/src/Angor/Client/Pages/View.razor b/src/Angor/Client/Pages/View.razor
index 17270879..093b3730 100644
--- a/src/Angor/Client/Pages/View.razor
+++ b/src/Angor/Client/Pages/View.razor
@@ -40,7 +40,7 @@
                         <a href="@projectExplorerLink" target="_blank">View the transaction on the explorer.</a>
                         <p class="card-text">Founder Key: @project.FounderKey</p>
                         <p class="card-text">Start Date: @project.StartDate.ToString("dd/MM/yyyy")</p>
-                        <p class="card-text">Penalty Date: @project.PenaltyDate.ToString("dd/MM/yyyy")</p>
+                        <p class="card-text">Penalty Days: @project.PenaltyDays</p>
                         <p class="card-text">Expiry Date: @project.ExpiryDate.ToString("dd/MM/yyyy")</p>
                         <p class="card-text">Target Amount: @project.TargetAmount</p>
                         <h5>Stages:</h5>
diff --git a/src/Angor/Shared/Models/ProjectInfo.cs b/src/Angor/Shared/Models/ProjectInfo.cs
index f9812c6e..8b5d33c5 100644
--- a/src/Angor/Shared/Models/ProjectInfo.cs
+++ b/src/Angor/Shared/Models/ProjectInfo.cs
@@ -13,7 +13,7 @@ public class ProjectInfo
     
     public string NostrPubKey { get; set; }
     public DateTime StartDate { get; set; }
-    public DateTime PenaltyDate { get; set; }
+    public int PenaltyDays { get; set; }
     public DateTime ExpiryDate { get; set; }
     public decimal TargetAmount { get; set; }
     public List<Stage> Stages { get; set; } = new();
diff --git a/src/Angor/Shared/Protocol/InvestmentOperations.cs b/src/Angor/Shared/Protocol/InvestmentOperations.cs
index 15355a81..639621a2 100644
--- a/src/Angor/Shared/Protocol/InvestmentOperations.cs
+++ b/src/Angor/Shared/Protocol/InvestmentOperations.cs
@@ -246,7 +246,7 @@ public List<Transaction> BuildRecoverInvestorFundsTransactions(InvestorContext c
 
                 var spendingScript = ScriptBuilder.GetInvestorPenaltyTransactionScript(
                     investorReceiveAddress,
-                    context.ProjectInfo.PenaltyDate);
+                    context.ProjectInfo.PenaltyDays);
                 
                 stageTransaction.Outputs.Add(new NBitcoin.TxOut(_.TxOut.Value,
                     new NBitcoin.Script(spendingScript.WitHash.ScriptPubKey.ToBytes())));
diff --git a/src/Angor/Shared/ScriptBuilder.cs b/src/Angor/Shared/Protocol/ScriptBuilder.cs
similarity index 94%
rename from src/Angor/Shared/ScriptBuilder.cs
rename to src/Angor/Shared/Protocol/ScriptBuilder.cs
index 3a2af59f..60718481 100644
--- a/src/Angor/Shared/ScriptBuilder.cs
+++ b/src/Angor/Shared/Protocol/ScriptBuilder.cs
@@ -1,10 +1,8 @@
+using Angor.Shared.Models;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.NBitcoin;
-using Blockcore.NBitcoin.Crypto;
-using System.Collections.Generic;
-using Angor.Shared.Models;
 
-namespace Angor.Shared;
+namespace Angor.Shared.Protocol;
 
 public class ScriptBuilder
 {
@@ -55,16 +53,19 @@ public static (PubKey investorKey, uint256? secretHash) GetInvestmentDataFromOpR
         return (pubKey, secretHash);
     }
 
-    public static Script GetInvestorPenaltyTransactionScript(string investorKey, DateTime punishmentLockTime)
+    public static Script GetInvestorPenaltyTransactionScript(string investorKey, int punishmentLockDays)
     {
-        var unixTime = Utils.DateTimeToUnixTime(punishmentLockTime);
-        
+        //var unixTime = Utils.DateTimeToUnixTime(punishmentLockTime);
+
+        //var totalSeconds = (uint)TimeSpan.FromDays(punishmentLockDays).TotalSeconds;
+        var sequence = new Sequence(TimeSpan.FromDays(punishmentLockDays));
+
         return new(new List<Op>
         {
             Op.GetPushOp(new NBitcoin.PubKey(investorKey).ToBytes()),
             OpcodeType.OP_CHECKSIGVERIFY,
-            Op.GetPushOp(unixTime),
-            OpcodeType.OP_CHECKLOCKTIMEVERIFY
+            Op.GetPushOp((uint)sequence),
+            OpcodeType.OP_CHECKSEQUENCEVERIFY
         });
     }
 
diff --git a/src/Angor/Shared/ProtocolNew/ISeederTransactionActions.cs b/src/Angor/Shared/ProtocolNew/ISeederTransactionActions.cs
index 7f793639..adf6329b 100644
--- a/src/Angor/Shared/ProtocolNew/ISeederTransactionActions.cs
+++ b/src/Angor/Shared/ProtocolNew/ISeederTransactionActions.cs
@@ -7,7 +7,7 @@ namespace Angor.Shared.ProtocolNew;
 public interface ISeederTransactionActions
 {
     Transaction CreateInvestmentTransaction(ProjectInfo projectInfo, string investorKey, uint256 investorSecretHash, long totalInvestmentAmount);
-    Transaction BuildRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, DateTime penaltyDate, string investorKey);
+    Transaction BuildRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, int penaltyDays, string investorKey);
     Transaction RecoverEndOfProjectFunds(string investmentTransactionHex, ProjectInfo projectInfo, int stageIndex, string investorReceiveAddress, string investorPrivateKey, FeeEstimation feeEstimation);
 
     Transaction AddSignaturesToRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction,
diff --git a/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs b/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
index e36f8b5e..2b3b02e0 100644
--- a/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
+++ b/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
@@ -89,7 +89,7 @@ public Transaction BuildRecoverInvestorFundsTransaction(ProjectInfo projectInfo,
     {
         var (investorKey, secretHash) = _projectScriptsBuilder.GetInvestmentDataFromOpReturnScript(investmentTransaction.Outputs.First(_ => _.ScriptPubKey.IsUnspendable).ScriptPubKey);
 
-        return _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDate, investorKey);
+        return _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDays, investorKey);
     }
 
     public Transaction BuildAndSignRecoverReleaseFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction,
@@ -99,12 +99,14 @@ public Transaction BuildAndSignRecoverReleaseFundsTransaction(ProjectInfo projec
 
         var spendingScript = _investmentScriptBuilder.GetInvestorPenaltyTransactionScript(
             investorKey,
-            projectInfo.PenaltyDate);
+            projectInfo.PenaltyDays);
 
         var network = _networkConfiguration.GetNetwork();
         var transaction = network.CreateTransaction();
 
-        transaction.LockTime = Utils.DateTimeToUnixTime(projectInfo.PenaltyDate.AddMinutes(1));
+        //transaction.LockTime = Utils.DateTimeToUnixTime(projectInfo.PenaltyDays.AddMinutes(1));
+
+        transaction.Version = 2; // to trigger bip68 rules
 
         // add the output address
         transaction.Outputs.Add(new Blockcore.Consensus.TransactionInfo.TxOut(Money.Zero, Blockcore.NBitcoin.BitcoinAddress.Create(investorReceiveAddress, network)));
@@ -115,7 +117,7 @@ public Transaction BuildAndSignRecoverReleaseFundsTransaction(ProjectInfo projec
             if (output.TxOut.ScriptPubKey == spendingScript.WitHash.ScriptPubKey)
             {
                 // this is a penalty output
-                transaction.Inputs.Add(new Blockcore.Consensus.TransactionInfo.TxIn(output.ToOutPoint()) { Sequence = new Blockcore.NBitcoin.Sequence(transaction.LockTime.Value)});
+                transaction.Inputs.Add(new Blockcore.Consensus.TransactionInfo.TxIn(output.ToOutPoint()) { Sequence = new Blockcore.NBitcoin.Sequence(TimeSpan.FromDays(projectInfo.PenaltyDays)) });
 
                 transaction.Outputs[0].Value += output.TxOut.Value;
             }
@@ -225,7 +227,7 @@ public Transaction AddSignaturesToRecoverSeederFundsTransaction(ProjectInfo proj
     {
         var (investorKey, secretHash) = _projectScriptsBuilder.GetInvestmentDataFromOpReturnScript(investmentTransaction.Outputs.First(_ => _.ScriptPubKey.IsUnspendable).ScriptPubKey);
 
-        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDate, investorKey);
+        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDays, investorKey);
 
         var nbitcoinNetwork = NetworkMapper.Map(_networkConfiguration.GetNetwork());
         var nbitcoinRecoveryTransaction = NBitcoin.Transaction.Parse(recoveryTransaction.ToHex(), nbitcoinNetwork);
@@ -267,7 +269,7 @@ public bool CheckInvestorRecoverySignatures(ProjectInfo projectInfo, Transaction
      {
          var (investorKey, secretHash) = _projectScriptsBuilder.GetInvestmentDataFromOpReturnScript(investmentTransaction.Outputs.First(_ => _.ScriptPubKey.IsUnspendable).ScriptPubKey);
 
-        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDate, investorKey);
+        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDays, investorKey);
 
         var nbitcoinNetwork = NetworkMapper.Map(_networkConfiguration.GetNetwork());
         var nBitcoinRecoveryTransaction = NBitcoin.Transaction.Parse(recoveryTransaction.ToHex(), nbitcoinNetwork);
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/IInvestmentScriptbuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/IInvestmentScriptbuilder.cs
index d86ddaa5..cbfee86a 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/IInvestmentScriptbuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/IInvestmentScriptbuilder.cs
@@ -6,7 +6,7 @@ namespace Angor.Shared.ProtocolNew.Scripts;
 
 public interface IInvestmentScriptBuilder
 {
-    Script GetInvestorPenaltyTransactionScript(string investorKey, DateTime punishmentLockTime);
+    Script GetInvestorPenaltyTransactionScript(string investorKey, int punishmentLockDays);
 
     ProjectScripts BuildProjectScriptsForStage(ProjectInfo projectInfo, string investorKey, int stageIndex,
         uint256? hashOfSecret = null);
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
index 9124db68..b83412a1 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
@@ -13,16 +13,20 @@ public InvestmentScriptBuilder(ISeederScriptTreeBuilder seederScriptTreeBuilder)
         _seederScriptTreeBuilder = seederScriptTreeBuilder;
     }
 
-    public Script GetInvestorPenaltyTransactionScript(string investorKey, DateTime punishmentLockTime)
+    public Script GetInvestorPenaltyTransactionScript(string investorKey, int punishmentLockDays)
     {
-        var unixTime = Utils.DateTimeToUnixTime(punishmentLockTime);
-        
+        // var unixTime = Utils.DateTimeToUnixTime(punishmentLockDays);
+
+        var sequence = new Sequence(TimeSpan.FromDays(punishmentLockDays));
+
+        //var totalSeconds = (uint)TimeSpan.FromDays(punishmentLockDays).TotalSeconds;
+
         return new(new List<Op>
         {
             Op.GetPushOp(new NBitcoin.PubKey(investorKey).ToBytes()),
             OpcodeType.OP_CHECKSIGVERIFY,
-            Op.GetPushOp(unixTime),
-            OpcodeType.OP_CHECKLOCKTIMEVERIFY
+            Op.GetPushOp((uint)sequence),
+            OpcodeType.OP_CHECKSEQUENCEVERIFY
         });
     }
 
diff --git a/src/Angor/Shared/ProtocolNew/SeederTransactionActions.cs b/src/Angor/Shared/ProtocolNew/SeederTransactionActions.cs
index 72484fca..288a2f6a 100644
--- a/src/Angor/Shared/ProtocolNew/SeederTransactionActions.cs
+++ b/src/Angor/Shared/ProtocolNew/SeederTransactionActions.cs
@@ -48,17 +48,17 @@ public Transaction CreateInvestmentTransaction(ProjectInfo projectInfo, string i
             totalInvestmentAmount);
     }
     
-    public Transaction BuildRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, DateTime penaltyDate,
+    public Transaction BuildRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, int penaltyDays,
         string investorKey)
     {
-        return _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, penaltyDate,
+        return _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, penaltyDays,
             investorKey);
     }
 
     public Transaction AddSignaturesToRecoverSeederFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction,
         string receiveAddress, SignatureInfo founderSignatures, string privateKey, string? secret)
     {
-        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDate, receiveAddress);
+        var recoveryTransaction = _investmentTransactionBuilder.BuildUpfrontRecoverFundsTransaction(projectInfo, investmentTransaction, projectInfo.PenaltyDays, receiveAddress);
 
         var (investorKey, secretHash) = _projectScriptsBuilder.GetInvestmentDataFromOpReturnScript(investmentTransaction.Outputs.First(_ => _.ScriptPubKey.IsUnspendable).ScriptPubKey);
         
diff --git a/src/Angor/Shared/ProtocolNew/TransactionBuilders/IInvestmentTransactionBuilder.cs b/src/Angor/Shared/ProtocolNew/TransactionBuilders/IInvestmentTransactionBuilder.cs
index 65a6eada..56031858 100644
--- a/src/Angor/Shared/ProtocolNew/TransactionBuilders/IInvestmentTransactionBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/TransactionBuilders/IInvestmentTransactionBuilder.cs
@@ -9,6 +9,6 @@ public interface IInvestmentTransactionBuilder
     Transaction BuildInvestmentTransaction(ProjectInfo projectInfo, Script opReturnScript,
         IEnumerable<ProjectScripts> projectScripts, long totalInvestmentAmount);
 
-    Transaction BuildUpfrontRecoverFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, DateTime penaltyDate,
+    Transaction BuildUpfrontRecoverFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, int penaltyDays,
         string investorKey);
 }
\ No newline at end of file
diff --git a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
index 9d42b4b9..46397053 100644
--- a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
@@ -48,11 +48,11 @@ public Transaction BuildInvestmentTransaction(ProjectInfo projectInfo, Script op
         return investmentTransaction;
     }
 
-    public Transaction BuildUpfrontRecoverFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, DateTime penaltyDate, string investorKey)
+    public Transaction BuildUpfrontRecoverFundsTransaction(ProjectInfo projectInfo, Transaction investmentTransaction, int penaltyDays, string investorKey)
     {
         var spendingScript = _investmentScriptBuilder.GetInvestorPenaltyTransactionScript(
             investorKey,
-            penaltyDate);
+            penaltyDays);
 
         var transaction = _networkConfiguration.GetNetwork().CreateTransaction();
         

From 004909093281c5bac9505035d83683ca1befe28c Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Tue, 14 Nov 2023 18:48:20 +0000
Subject: [PATCH 2/6] move AngorScripts.CreateStage to ITaprootScriptBuilder

---
 .../ProtocolNew/InvestmentIntegrationsTests.cs           | 4 ++--
 .../InvestmentTransactionBuilderTest.cs                  | 3 ++-
 src/Angor.Test/WalletOperationsTest.cs                   | 2 +-
 src/Angor/Client/Program.cs                              | 1 -
 src/Angor/Shared/{Protocol => Models}/FounderContext.cs  | 6 ++----
 src/Angor/Shared/{Protocol => Models}/InvestorContext.cs | 6 ++----
 .../Shared/ProtocolNew/Scripts/ITaprootScriptBuilder.cs  | 2 ++
 .../Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs   | 9 +++++++++
 .../TransactionBuilders/InvestmentTransactionBuilder.cs  | 6 ++++--
 9 files changed, 24 insertions(+), 15 deletions(-)
 rename src/Angor/Shared/{Protocol => Models}/FounderContext.cs (81%)
 rename src/Angor/Shared/{Protocol => Models}/InvestorContext.cs (87%)

diff --git a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
index 7ee3fa90..b7a1c671 100644
--- a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
+++ b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
@@ -79,7 +79,7 @@ public InvestmentIntegrationsTests()
                     new ProjectScriptsBuilder(_derivationOperations),
                     new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
                 new InvestmentTransactionBuilder(_networkConfiguration.Object,
-                    new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
+                    new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
                 new TaprootScriptBuilder(), _networkConfiguration.Object);
 
             _investorTransactionActions = new InvestorTransactionActions(new NullLogger<InvestorTransactionActions>(),
@@ -90,7 +90,7 @@ public InvestmentIntegrationsTests()
                     new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
                 new InvestmentTransactionBuilder(_networkConfiguration.Object,
                     new ProjectScriptsBuilder(_derivationOperations),
-                    new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
+                    new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
                 new TaprootScriptBuilder(), _networkConfiguration.Object);
 
             _founderTransactionActions = new FounderTransactionActions(new NullLogger<FounderTransactionActions>(), _networkConfiguration.Object,
diff --git a/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs b/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
index a03d9ba9..a355759b 100644
--- a/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
+++ b/src/Angor.Test/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilderTest.cs
@@ -25,7 +25,8 @@ public InvestmentTransactionBuilderTest()
         
         _sut = new InvestmentTransactionBuilder(_networkConfiguration.Object,
             _projectScriptsBuilder.Object,
-            _investmentScriptBuilder.Object);
+            _investmentScriptBuilder.Object,
+            new TaprootScriptBuilder());
     }
     
     private Script GivenTheAngorFeeScript(ProjectInfo projectInvestmentInfo)
diff --git a/src/Angor.Test/WalletOperationsTest.cs b/src/Angor.Test/WalletOperationsTest.cs
index 50acb5ef..2f515cf0 100644
--- a/src/Angor.Test/WalletOperationsTest.cs
+++ b/src/Angor.Test/WalletOperationsTest.cs
@@ -45,7 +45,7 @@ public WalletOperationsTest()
             new InvestmentScriptBuilder(new SeederScriptTreeBuilder()),
             new ProjectScriptsBuilder(_derivationOperations),
             new SpendingTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
-            new InvestmentTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
+            new InvestmentTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
             new TaprootScriptBuilder(),
             _networkConfiguration.Object);
 
diff --git a/src/Angor/Client/Program.cs b/src/Angor/Client/Program.cs
index bb5539bc..3e31cf23 100644
--- a/src/Angor/Client/Program.cs
+++ b/src/Angor/Client/Program.cs
@@ -31,7 +31,6 @@
 builder.Services.AddScoped<IClipboardService, ClipboardService>();
 builder.Services.AddScoped<IDerivationOperations, DerivationOperations>();
 builder.Services.AddScoped<NavMenuState>();
-builder.Services.AddScoped<InvestmentOperations>();
 
 builder.Services.AddScoped<IIndexerService, IndexerService>();
 builder.Services.AddScoped<IRelayService, RelayService>();
diff --git a/src/Angor/Shared/Protocol/FounderContext.cs b/src/Angor/Shared/Models/FounderContext.cs
similarity index 81%
rename from src/Angor/Shared/Protocol/FounderContext.cs
rename to src/Angor/Shared/Models/FounderContext.cs
index 8d538ac3..0ae66209 100644
--- a/src/Angor/Shared/Protocol/FounderContext.cs
+++ b/src/Angor/Shared/Models/FounderContext.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using Angor.Shared.Models;
+namespace Angor.Shared.Models;
 
 /// <summary>
 /// Contains all the requisite information for a founder.
@@ -11,4 +9,4 @@ public class FounderContext
     public ProjectSeeders ProjectSeeders { get; set; }
     public string ChangeAddress { get; set; }
     public List<string> InvestmentTrasnactionsHex { get; set; } = new ();
-}
+}
\ No newline at end of file
diff --git a/src/Angor/Shared/Protocol/InvestorContext.cs b/src/Angor/Shared/Models/InvestorContext.cs
similarity index 87%
rename from src/Angor/Shared/Protocol/InvestorContext.cs
rename to src/Angor/Shared/Models/InvestorContext.cs
index 96502bba..7ed5941c 100644
--- a/src/Angor/Shared/Protocol/InvestorContext.cs
+++ b/src/Angor/Shared/Models/InvestorContext.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using Angor.Shared.Models;
+namespace Angor.Shared.Models;
 
 /// <summary>
 /// Contains all the requisite information for an investor to formulate an investment transaction.
@@ -21,4 +19,4 @@ public class InvestorContext
     // ==============================================
 
     public string ChangeAddress { get; set; }
-}
+}
\ No newline at end of file
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/ITaprootScriptBuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/ITaprootScriptBuilder.cs
index e62ec35f..685a86d8 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/ITaprootScriptBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/ITaprootScriptBuilder.cs
@@ -6,6 +6,8 @@ namespace Angor.Shared.ProtocolNew.Scripts;
 
 public interface ITaprootScriptBuilder
 {
+    Script CreateStage(Blockcore.Networks.Network network, ProjectScripts scripts);
+
     public Script CreateControlBlock(ProjectScripts scripts, Expression<Func<ProjectScripts, Script>> func);
 
     (Script controlBlock, Script execute, Script[] secrets) CreateControlSeederSecrets(ProjectScripts scripts, int threshold,
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
index 30de8e66..7adf2112 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
@@ -11,6 +11,15 @@ namespace Angor.Shared.ProtocolNew.Scripts;
 
 public class TaprootScriptBuilder : ITaprootScriptBuilder
 {
+    public Script CreateStage(Blockcore.Networks.Network network, ProjectScripts scripts)
+    {
+        var treeInfo = BuildTaprootSpendInfo(scripts);
+
+        var address = treeInfo.OutputPubKey.GetAddress(NetworkMapper.Map(network));
+
+        return new Script(address.ScriptPubKey.ToBytes());
+    }
+
     public Script CreateControlBlock(ProjectScripts scripts, Expression<Func<ProjectScripts,Script>> scriptSelector)
     {
         var treeInfo = BuildTaprootSpendInfo(scripts);
diff --git a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
index 46397053..1f894f08 100644
--- a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
@@ -13,13 +13,15 @@ public class InvestmentTransactionBuilder : IInvestmentTransactionBuilder
     private readonly INetworkConfiguration _networkConfiguration;
     private readonly IProjectScriptsBuilder _projectScriptsBuilder;
     private readonly IInvestmentScriptBuilder _investmentScriptBuilder;
+    private readonly ITaprootScriptBuilder _taprootScriptBuilder;
 
     public InvestmentTransactionBuilder(INetworkConfiguration networkConfiguration, IProjectScriptsBuilder projectScriptsBuilder, 
-        IInvestmentScriptBuilder investmentScriptBuilder)
+        IInvestmentScriptBuilder investmentScriptBuilder, ITaprootScriptBuilder taprootScriptBuilder)
     {
         _networkConfiguration = networkConfiguration;
         _projectScriptsBuilder = projectScriptsBuilder;
         _investmentScriptBuilder = investmentScriptBuilder;
+        _taprootScriptBuilder = taprootScriptBuilder;
     }
 
     public Transaction BuildInvestmentTransaction(ProjectInfo projectInfo, Script opReturnScript, 
@@ -37,7 +39,7 @@ public Transaction BuildInvestmentTransaction(ProjectInfo projectInfo, Script op
         var investorInfoOutput = new TxOut(new Money(0), opReturnScript);
         investmentTransaction.AddOutput(investorInfoOutput);
 
-        var stagesScripts = projectScripts.Select(_ => AngorScripts.CreateStage(network, _)); //TODO replace angor scripts
+        var stagesScripts = projectScripts.Select(_ => _taprootScriptBuilder.CreateStage(network, _));
 
         var stagesOutputs = stagesScripts.Select((_, i) =>
             new TxOut(new Money(Convert.ToInt64(totalInvestmentAmount * (projectInfo.Stages[i].AmountToRelease / 100))),

From 7aaf2ae49f413bb5611f725ce18e3d9e7802fa1c Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Tue, 14 Nov 2023 18:50:37 +0000
Subject: [PATCH 3/6] Move the folder protocol to the test project

---
 src/Angor.Test/DerivationOperationsTest.cs                 | 1 -
 src/Angor.Test/InvestmentOperationsTest.cs                 | 1 +
 src/{Angor/Shared => Angor.Test}/Protocol/AngorScripts.cs  | 3 ++-
 .../Shared => Angor.Test}/Protocol/InvestmentOperations.cs | 7 ++++---
 .../Shared => Angor.Test}/Protocol/ProjectOperations.cs    | 2 +-
 src/{Angor/Shared => Angor.Test}/Protocol/ScriptBuilder.cs | 3 ++-
 src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs | 1 +
 src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs  | 1 +
 src/Angor.Test/ScriptTest.cs                               | 2 +-
 src/Angor.Test/ScriptThresholdTest.cs                      | 2 +-
 src/Angor/Client/Pages/Invest.razor                        | 1 -
 .../Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs     | 1 -
 .../TransactionBuilders/InvestmentTransactionBuilder.cs    | 1 -
 13 files changed, 14 insertions(+), 12 deletions(-)
 rename src/{Angor/Shared => Angor.Test}/Protocol/AngorScripts.cs (99%)
 rename src/{Angor/Shared => Angor.Test}/Protocol/InvestmentOperations.cs (99%)
 rename src/{Angor/Shared => Angor.Test}/Protocol/ProjectOperations.cs (96%)
 rename src/{Angor/Shared => Angor.Test}/Protocol/ScriptBuilder.cs (99%)

diff --git a/src/Angor.Test/DerivationOperationsTest.cs b/src/Angor.Test/DerivationOperationsTest.cs
index 6296b3cf..dd856d3c 100644
--- a/src/Angor.Test/DerivationOperationsTest.cs
+++ b/src/Angor.Test/DerivationOperationsTest.cs
@@ -1,7 +1,6 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.Networks;
-using Angor.Shared.Protocol;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.BIP32;
diff --git a/src/Angor.Test/InvestmentOperationsTest.cs b/src/Angor.Test/InvestmentOperationsTest.cs
index c3f8ef5d..24cf98ee 100644
--- a/src/Angor.Test/InvestmentOperationsTest.cs
+++ b/src/Angor.Test/InvestmentOperationsTest.cs
@@ -1,6 +1,7 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.Networks;
+using Angor.Test.Protocol;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.Crypto;
 using Blockcore.NBitcoin.DataEncoders;
diff --git a/src/Angor/Shared/Protocol/AngorScripts.cs b/src/Angor.Test/Protocol/AngorScripts.cs
similarity index 99%
rename from src/Angor/Shared/Protocol/AngorScripts.cs
rename to src/Angor.Test/Protocol/AngorScripts.cs
index 2c3a32c5..72331d71 100644
--- a/src/Angor/Shared/Protocol/AngorScripts.cs
+++ b/src/Angor.Test/Protocol/AngorScripts.cs
@@ -1,5 +1,6 @@
 using System.Linq.Expressions;
 using System.Text;
+using Angor.Shared;
 using Angor.Shared.Models;
 using Blockcore.NBitcoin;
 using NBitcoin;
@@ -7,7 +8,7 @@
 using Script = Blockcore.Consensus.ScriptInfo.Script;
 
 
-namespace Angor.Shared.Protocol
+namespace Angor.Test.Protocol
 {
     public class AngorScripts
     {
diff --git a/src/Angor/Shared/Protocol/InvestmentOperations.cs b/src/Angor.Test/Protocol/InvestmentOperations.cs
similarity index 99%
rename from src/Angor/Shared/Protocol/InvestmentOperations.cs
rename to src/Angor.Test/Protocol/InvestmentOperations.cs
index 639621a2..fc8a562d 100644
--- a/src/Angor/Shared/Protocol/InvestmentOperations.cs
+++ b/src/Angor.Test/Protocol/InvestmentOperations.cs
@@ -1,10 +1,9 @@
-using Angor.Shared;
+using System.Text;
+using Angor.Shared;
 using Angor.Shared.Models;
-using Angor.Shared.Protocol;
 using Blockcore.NBitcoin.DataEncoders;
 using NBitcoin;
 using NBitcoin.Policy;
-using System.Text;
 using BitcoinAddress = Blockcore.NBitcoin.BitcoinAddress;
 using FeeRate = Blockcore.NBitcoin.FeeRate;
 using IndexedTxOut = NBitcoin.IndexedTxOut;
@@ -21,6 +20,8 @@
 using Utils = NBitcoin.Utils;
 using WitScript = NBitcoin.WitScript;
 
+namespace Angor.Test.Protocol;
+
 public class InvestmentOperations
 {
     private readonly IWalletOperations _walletOperations;
diff --git a/src/Angor/Shared/Protocol/ProjectOperations.cs b/src/Angor.Test/Protocol/ProjectOperations.cs
similarity index 96%
rename from src/Angor/Shared/Protocol/ProjectOperations.cs
rename to src/Angor.Test/Protocol/ProjectOperations.cs
index e3aae87d..227b9745 100644
--- a/src/Angor/Shared/Protocol/ProjectOperations.cs
+++ b/src/Angor.Test/Protocol/ProjectOperations.cs
@@ -3,7 +3,7 @@
 using Blockcore.NBitcoin;
 using Blockcore.Networks;
 
-namespace Angor.Shared.Protocol;
+namespace Angor.Test.Protocol;
 
 public class ProjectOperations
 {
diff --git a/src/Angor/Shared/Protocol/ScriptBuilder.cs b/src/Angor.Test/Protocol/ScriptBuilder.cs
similarity index 99%
rename from src/Angor/Shared/Protocol/ScriptBuilder.cs
rename to src/Angor.Test/Protocol/ScriptBuilder.cs
index 60718481..98565fa0 100644
--- a/src/Angor/Shared/Protocol/ScriptBuilder.cs
+++ b/src/Angor.Test/Protocol/ScriptBuilder.cs
@@ -1,8 +1,9 @@
+using Angor.Shared;
 using Angor.Shared.Models;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.NBitcoin;
 
-namespace Angor.Shared.Protocol;
+namespace Angor.Test.Protocol;
 
 public class ScriptBuilder
 {
diff --git a/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs b/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
index 0a872625..a13e0046 100644
--- a/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
+++ b/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
@@ -4,6 +4,7 @@
 using Angor.Shared.ProtocolNew;
 using Angor.Shared.ProtocolNew.Scripts;
 using Angor.Shared.ProtocolNew.TransactionBuilders;
+using Angor.Test.Protocol;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.DataEncoders;
 using Microsoft.Extensions.Logging.Abstractions;
diff --git a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
index b7a1c671..c35c4f37 100644
--- a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
+++ b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
@@ -4,6 +4,7 @@
 using Angor.Shared.ProtocolNew;
 using Angor.Shared.ProtocolNew.Scripts;
 using Angor.Shared.ProtocolNew.TransactionBuilders;
+using Angor.Test.Protocol;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.Consensus.TransactionInfo;
 using Blockcore.NBitcoin;
diff --git a/src/Angor.Test/ScriptTest.cs b/src/Angor.Test/ScriptTest.cs
index 3729d6ed..2f7f2935 100644
--- a/src/Angor.Test/ScriptTest.cs
+++ b/src/Angor.Test/ScriptTest.cs
@@ -1,7 +1,7 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.Networks;
-using Angor.Shared.Protocol;
+using Angor.Test.Protocol;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.Crypto;
 
diff --git a/src/Angor.Test/ScriptThresholdTest.cs b/src/Angor.Test/ScriptThresholdTest.cs
index 3b613049..87063fa9 100644
--- a/src/Angor.Test/ScriptThresholdTest.cs
+++ b/src/Angor.Test/ScriptThresholdTest.cs
@@ -1,5 +1,5 @@
 using Angor.Shared;
-using Angor.Shared.Protocol;
+using Angor.Test.Protocol;
 
 namespace Angor.Test
 {
diff --git a/src/Angor/Client/Pages/Invest.razor b/src/Angor/Client/Pages/Invest.razor
index 3c6ea5b1..bb7f03db 100644
--- a/src/Angor/Client/Pages/Invest.razor
+++ b/src/Angor/Client/Pages/Invest.razor
@@ -2,7 +2,6 @@
 @using Angor.Shared
 @using Angor.Client.Storage
 @using Angor.Shared.Models
-@using Angor.Shared.Protocol
 @using Blockcore.Consensus.TransactionInfo
 @using Blockcore.NBitcoin
 @using Angor.Client.Services
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
index 7adf2112..4365cf29 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/TaprootScriptBuilder.cs
@@ -1,7 +1,6 @@
 using System.Linq.Expressions;
 using System.Text;
 using Angor.Shared.Models;
-using Angor.Shared.Protocol;
 using Blockcore.NBitcoin;
 using NBitcoin;
 using NBitcoin.Crypto;
diff --git a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
index 1f894f08..867ed8e6 100644
--- a/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/TransactionBuilders/InvestmentTransactionBuilder.cs
@@ -1,5 +1,4 @@
 using Angor.Shared.Models;
-using Angor.Shared.Protocol;
 using Angor.Shared.ProtocolNew.Scripts;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.Consensus.TransactionInfo;

From 41327d2f7d774fa6cb20357418c5cf895ba710f8 Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Thu, 16 Nov 2023 11:19:52 +0000
Subject: [PATCH 4/6] Act on review

---
 src/Angor.Test/{Protocol => DataBuilders}/AngorScripts.cs     | 2 +-
 .../{Protocol => DataBuilders}/InvestmentOperations.cs        | 2 +-
 .../{Protocol => DataBuilders}/ProjectOperations.cs           | 2 +-
 src/Angor.Test/{Protocol => DataBuilders}/ScriptBuilder.cs    | 2 +-
 src/Angor.Test/InvestmentOperationsTest.cs                    | 2 +-
 src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs    | 2 +-
 src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs     | 2 +-
 src/Angor.Test/ScriptTest.cs                                  | 2 +-
 src/Angor.Test/ScriptThresholdTest.cs                         | 2 +-
 src/Angor/Client/Pages/Create.razor                           | 4 ++--
 src/Angor/Client/Pages/Penalties.razor                        | 2 --
 src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs    | 2 --
 .../Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs     | 4 ----
 13 files changed, 11 insertions(+), 19 deletions(-)
 rename src/Angor.Test/{Protocol => DataBuilders}/AngorScripts.cs (99%)
 rename src/Angor.Test/{Protocol => DataBuilders}/InvestmentOperations.cs (99%)
 rename src/Angor.Test/{Protocol => DataBuilders}/ProjectOperations.cs (96%)
 rename src/Angor.Test/{Protocol => DataBuilders}/ScriptBuilder.cs (99%)

diff --git a/src/Angor.Test/Protocol/AngorScripts.cs b/src/Angor.Test/DataBuilders/AngorScripts.cs
similarity index 99%
rename from src/Angor.Test/Protocol/AngorScripts.cs
rename to src/Angor.Test/DataBuilders/AngorScripts.cs
index 72331d71..98c9b6fa 100644
--- a/src/Angor.Test/Protocol/AngorScripts.cs
+++ b/src/Angor.Test/DataBuilders/AngorScripts.cs
@@ -8,7 +8,7 @@
 using Script = Blockcore.Consensus.ScriptInfo.Script;
 
 
-namespace Angor.Test.Protocol
+namespace Angor.Test.DataBuilders
 {
     public class AngorScripts
     {
diff --git a/src/Angor.Test/Protocol/InvestmentOperations.cs b/src/Angor.Test/DataBuilders/InvestmentOperations.cs
similarity index 99%
rename from src/Angor.Test/Protocol/InvestmentOperations.cs
rename to src/Angor.Test/DataBuilders/InvestmentOperations.cs
index fc8a562d..c94f2b1c 100644
--- a/src/Angor.Test/Protocol/InvestmentOperations.cs
+++ b/src/Angor.Test/DataBuilders/InvestmentOperations.cs
@@ -20,7 +20,7 @@
 using Utils = NBitcoin.Utils;
 using WitScript = NBitcoin.WitScript;
 
-namespace Angor.Test.Protocol;
+namespace Angor.Test.DataBuilders;
 
 public class InvestmentOperations
 {
diff --git a/src/Angor.Test/Protocol/ProjectOperations.cs b/src/Angor.Test/DataBuilders/ProjectOperations.cs
similarity index 96%
rename from src/Angor.Test/Protocol/ProjectOperations.cs
rename to src/Angor.Test/DataBuilders/ProjectOperations.cs
index 227b9745..a2d4dae8 100644
--- a/src/Angor.Test/Protocol/ProjectOperations.cs
+++ b/src/Angor.Test/DataBuilders/ProjectOperations.cs
@@ -3,7 +3,7 @@
 using Blockcore.NBitcoin;
 using Blockcore.Networks;
 
-namespace Angor.Test.Protocol;
+namespace Angor.Test.DataBuilders;
 
 public class ProjectOperations
 {
diff --git a/src/Angor.Test/Protocol/ScriptBuilder.cs b/src/Angor.Test/DataBuilders/ScriptBuilder.cs
similarity index 99%
rename from src/Angor.Test/Protocol/ScriptBuilder.cs
rename to src/Angor.Test/DataBuilders/ScriptBuilder.cs
index 98565fa0..8bf2b801 100644
--- a/src/Angor.Test/Protocol/ScriptBuilder.cs
+++ b/src/Angor.Test/DataBuilders/ScriptBuilder.cs
@@ -3,7 +3,7 @@
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.NBitcoin;
 
-namespace Angor.Test.Protocol;
+namespace Angor.Test.DataBuilders;
 
 public class ScriptBuilder
 {
diff --git a/src/Angor.Test/InvestmentOperationsTest.cs b/src/Angor.Test/InvestmentOperationsTest.cs
index 24cf98ee..4bb8cb6d 100644
--- a/src/Angor.Test/InvestmentOperationsTest.cs
+++ b/src/Angor.Test/InvestmentOperationsTest.cs
@@ -1,7 +1,7 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.Networks;
-using Angor.Test.Protocol;
+using Angor.Test.DataBuilders;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.Crypto;
 using Blockcore.NBitcoin.DataEncoders;
diff --git a/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs b/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
index a13e0046..c4976ba9 100644
--- a/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
+++ b/src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
@@ -4,7 +4,7 @@
 using Angor.Shared.ProtocolNew;
 using Angor.Shared.ProtocolNew.Scripts;
 using Angor.Shared.ProtocolNew.TransactionBuilders;
-using Angor.Test.Protocol;
+using Angor.Test.DataBuilders;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.DataEncoders;
 using Microsoft.Extensions.Logging.Abstractions;
diff --git a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
index c35c4f37..1cf37653 100644
--- a/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
+++ b/src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
@@ -4,7 +4,7 @@
 using Angor.Shared.ProtocolNew;
 using Angor.Shared.ProtocolNew.Scripts;
 using Angor.Shared.ProtocolNew.TransactionBuilders;
-using Angor.Test.Protocol;
+using Angor.Test.DataBuilders;
 using Blockcore.Consensus.ScriptInfo;
 using Blockcore.Consensus.TransactionInfo;
 using Blockcore.NBitcoin;
diff --git a/src/Angor.Test/ScriptTest.cs b/src/Angor.Test/ScriptTest.cs
index 2f7f2935..534aa413 100644
--- a/src/Angor.Test/ScriptTest.cs
+++ b/src/Angor.Test/ScriptTest.cs
@@ -1,7 +1,7 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.Networks;
-using Angor.Test.Protocol;
+using Angor.Test.DataBuilders;
 using Blockcore.NBitcoin;
 using Blockcore.NBitcoin.Crypto;
 
diff --git a/src/Angor.Test/ScriptThresholdTest.cs b/src/Angor.Test/ScriptThresholdTest.cs
index 87063fa9..254d2f8f 100644
--- a/src/Angor.Test/ScriptThresholdTest.cs
+++ b/src/Angor.Test/ScriptThresholdTest.cs
@@ -1,5 +1,5 @@
 using Angor.Shared;
-using Angor.Test.Protocol;
+using Angor.Test.DataBuilders;
 
 namespace Angor.Test
 {
diff --git a/src/Angor/Client/Pages/Create.razor b/src/Angor/Client/Pages/Create.razor
index 772e025f..23d31044 100644
--- a/src/Angor/Client/Pages/Create.razor
+++ b/src/Angor/Client/Pages/Create.razor
@@ -55,8 +55,8 @@
 
         <!-- Penalty Date -->
         <div class="mb-3">
-            <label for="penaltyDate" class="form-label">Penalty Days</label>
-            <InputNumber id="penaltyDate" @bind-Value="project.PenaltyDays" class="form-control" />
+            <label for="penaltyDays" class="form-label">Penalty Days</label>
+            <InputNumber id="penaltyDays" @bind-Value="project.PenaltyDays" class="form-control" />
         </div>
 
         <!-- Expiry Date -->
diff --git a/src/Angor/Client/Pages/Penalties.razor b/src/Angor/Client/Pages/Penalties.razor
index 1a8010f3..52c961cd 100644
--- a/src/Angor/Client/Pages/Penalties.razor
+++ b/src/Angor/Client/Pages/Penalties.razor
@@ -110,8 +110,6 @@
                     {
                         ProjectIdentifier = signatureInfo.ProjectIdentifier,
                         RecoveryTransactionId = signatureInfo.RecoveryTransactionId,
-                        //DaysLeftForPenalty = (project.PenaltyDays - DateTime.Now).Days,
-                        //IsExpired = (project.PenaltyDays - DateTime.Now).Days <= 0,
                         IsReleased = !string.IsNullOrEmpty(signatureInfo.RecoveryReleaseTransactionId),
                     });
                 }
diff --git a/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs b/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
index 2b3b02e0..ad5c1240 100644
--- a/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
+++ b/src/Angor/Shared/ProtocolNew/InvestorTransactionActions.cs
@@ -104,8 +104,6 @@ public Transaction BuildAndSignRecoverReleaseFundsTransaction(ProjectInfo projec
         var network = _networkConfiguration.GetNetwork();
         var transaction = network.CreateTransaction();
 
-        //transaction.LockTime = Utils.DateTimeToUnixTime(projectInfo.PenaltyDays.AddMinutes(1));
-
         transaction.Version = 2; // to trigger bip68 rules
 
         // add the output address
diff --git a/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs b/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
index b83412a1..a24f11c5 100644
--- a/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
+++ b/src/Angor/Shared/ProtocolNew/Scripts/InvestmentScriptBuilder.cs
@@ -15,12 +15,8 @@ public InvestmentScriptBuilder(ISeederScriptTreeBuilder seederScriptTreeBuilder)
 
     public Script GetInvestorPenaltyTransactionScript(string investorKey, int punishmentLockDays)
     {
-        // var unixTime = Utils.DateTimeToUnixTime(punishmentLockDays);
-
         var sequence = new Sequence(TimeSpan.FromDays(punishmentLockDays));
 
-        //var totalSeconds = (uint)TimeSpan.FromDays(punishmentLockDays).TotalSeconds;
-
         return new(new List<Op>
         {
             Op.GetPushOp(new NBitcoin.PubKey(investorKey).ToBytes()),

From 469ecbf3186a8871db334de4765749b90d4f6608 Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Fri, 17 Nov 2023 17:43:45 +0000
Subject: [PATCH 5/6] flow now working

---
 src/Angor/Client/Pages/Invest.razor           |  4 ++--
 src/Angor/Client/Pages/Invest.razor.js        |  4 ++--
 src/Angor/Server/Program.cs                   | 10 +++++++++-
 src/Angor/Server/TestNostrSigningFromRelay.cs | 19 ++++++++++++++++++-
 src/Angor/Server/TestStorageService.cs        |  9 ++++++++-
 5 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/src/Angor/Client/Pages/Invest.razor b/src/Angor/Client/Pages/Invest.razor
index 31ec31b5..db62efea 100644
--- a/src/Angor/Client/Pages/Invest.razor
+++ b/src/Angor/Client/Pages/Invest.razor
@@ -416,7 +416,7 @@
 
         if (operationResult.Success)
         {
-            notificationComponent.ShowNotificationMessage("Project created", 1);
+            notificationComponent.ShowNotificationMessage("Signature request sent", 1);
         }
         else
         {
@@ -436,7 +436,7 @@
 
         _Logger.LogInformation("signature : " + signatureJson);
 
-        recoverySigs ??= new SignatureInfo();
+        recoverySigs ??= new SignatureInfo() { ProjectIdentifier = project.ProjectIdentifier};
 
         recoverySigs.Signatures.Add(new SignatureInfoItem
         {
diff --git a/src/Angor/Client/Pages/Invest.razor.js b/src/Angor/Client/Pages/Invest.razor.js
index 767e62c4..cd6cff28 100644
--- a/src/Angor/Client/Pages/Invest.razor.js
+++ b/src/Angor/Client/Pages/Invest.razor.js
@@ -1,13 +1,13 @@
 import {nip04} from 'https://cdn.jsdelivr.net/npm/nostr-tools@1.17.0/+esm'
 
 export function encryptNostr(sk1,pk2, message){
-    debugger;
+    //debugger;
     console.log("encrypting the nostr message to pub key " + pk2)
     return  nip04.encrypt(sk1,pk2, message)
 }
 
 export function decryptNostr(sk2,pk1, message){
-    debugger;
+    //debugger;
     console.log("decrypting the nostr message from pub key " + pk1)
     return  nip04.decrypt(sk2,pk1,message);
 }
\ No newline at end of file
diff --git a/src/Angor/Server/Program.cs b/src/Angor/Server/Program.cs
index b38a0520..d2e5d8a8 100644
--- a/src/Angor/Server/Program.cs
+++ b/src/Angor/Server/Program.cs
@@ -7,6 +7,7 @@
 using DataConfigOptions = Angor.Server.DataConfigOptions;
 using Angor.Client;
 using Angor.Shared;
+using Blockcore.AtomicSwaps.Server.Controllers;
 
 var builder = WebApplication.CreateBuilder(args);
 
@@ -61,6 +62,13 @@
 app.MapControllers();
 app.MapFallbackToFile("index.html");
 
-
+// trigger the relay to send over messages
+var storage = app.Services.GetService<TestStorageService>();
+var relay = app.Services.GetService<ITestNostrSigningFromRelay>();
+var projects = storage.GetAllKeys().Result;
+foreach (var project in projects)
+{
+    relay.SignTransactionsFromNostrAsync(project.Key).Wait();
+}
 
 app.Run();
diff --git a/src/Angor/Server/TestNostrSigningFromRelay.cs b/src/Angor/Server/TestNostrSigningFromRelay.cs
index 6ace0ab7..b07a273d 100644
--- a/src/Angor/Server/TestNostrSigningFromRelay.cs
+++ b/src/Angor/Server/TestNostrSigningFromRelay.cs
@@ -4,6 +4,7 @@
 using Angor.Shared;
 using Angor.Shared.Models;
 using Angor.Shared.ProtocolNew;
+using Angor.Shared.Utilities;
 using Newtonsoft.Json;
 using Nostr.Client.Client;
 using Nostr.Client.Communicator;
@@ -104,7 +105,8 @@ public async Task SignTransactionsFromNostrAsync(string projectIdentifier)
             .Subscribe(_ =>
             {
                 _clientLogger.LogInformation("application specific data" + _.Event.Content);
-                _storage.Add(System.Text.Json.JsonSerializer.Deserialize<ProjectInfo>(_.Event.Content));
+                var data = System.Text.Json.JsonSerializer.Deserialize<ProjectInfo>(_.Event.Content, settings);
+                _storage.Add(data);
             });
 
         _nostrClient.Streams.EventStream.Where(_ => _.Subscription == nostrPubKey + "2")
@@ -175,6 +177,20 @@ private SignatureInfo signProject(string transactionHex,ProjectInfo info, string
 
         return sig;
     }
+
+    private JsonSerializerOptions settings => new()
+    {
+        // Equivalent to Formatting = Formatting.None
+        WriteIndented = false,
+
+        // Equivalent to NullValueHandling = NullValueHandling.Ignore
+        DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
+
+        // PropertyNamingPolicy equivalent to CamelCasePropertyNamesContractResolver
+        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+
+        Converters = { new UnixDateTimeConverter() }
+    };
 }
 
 public interface ITestNostrSigningFromRelay
@@ -182,3 +198,4 @@ public interface ITestNostrSigningFromRelay
     public Task SignTransactionsFromNostrAsync(string projectIdentifier);
 }
 
+
diff --git a/src/Angor/Server/TestStorageService.cs b/src/Angor/Server/TestStorageService.cs
index 746e1866..d8dfb2fc 100644
--- a/src/Angor/Server/TestStorageService.cs
+++ b/src/Angor/Server/TestStorageService.cs
@@ -110,7 +110,14 @@ public async Task<ProjectKeys> GetKeys(string projectid)
 
             return context.ProjectKeys.First(_ => _.Key == projectid);
         }
-        
+
+        public async Task<IEnumerable<ProjectKeys>> GetAllKeys()
+        {
+            await using var context = new ProjectContext(dbPath);
+
+            return context.ProjectKeys.ToList();
+        }
+
         public async Task<string> GetKey(string projectid)
         {
             await using var context = new ProjectContext(dbPath);

From bd77ca6b386c4d4c858a934bd10a66fa01ee699e Mon Sep 17 00:00:00 2001
From: dangershony <dan.gershony@gmail.com>
Date: Fri, 17 Nov 2023 18:42:38 +0000
Subject: [PATCH 6/6] use a single call to pass sigs between relay and and
 browser

---
 src/Angor/Client/Pages/Invest.razor           | 37 +++++++++++++------
 src/Angor/Server/TestNostrSigningFromRelay.cs | 29 ++++++---------
 2 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/src/Angor/Client/Pages/Invest.razor b/src/Angor/Client/Pages/Invest.razor
index db62efea..1c671e77 100644
--- a/src/Angor/Client/Pages/Invest.razor
+++ b/src/Angor/Client/Pages/Invest.razor
@@ -5,10 +5,12 @@
 @using Blockcore.NBitcoin
 @using Angor.Client.Services
 @using Angor.Shared.ProtocolNew
+@using Angor.Shared.Utilities
 @using Blockcore.NBitcoin.DataEncoders
 @using JSException = Microsoft.JSInterop.JSException
 @using Money = Blockcore.NBitcoin.Money
 @using Transaction = Blockcore.Consensus.TransactionInfo.Transaction
+@using System.Text.Json
 
 @inject IJSRuntime JS
 
@@ -416,7 +418,7 @@
 
         if (operationResult.Success)
         {
-            notificationComponent.ShowNotificationMessage("Signature request sent", 1);
+            notificationComponent.ShowNotificationMessage("Signature request sent", 5);
         }
         else
         {
@@ -426,29 +428,40 @@
 
     private async Task HandleSignatureReceivedAsync(string? nostrPrivateKeyHex, string _)
     {
+        recoverySigs ??= new SignatureInfo() { ProjectIdentifier = project.ProjectIdentifier};
+
         var signatureJson = await javascriptNostrToolsModule.InvokeAsync<string>(
             "decryptNostr",
             nostrPrivateKeyHex,
             project.NostrPubKey,
             _);
 
-        var signature = System.Text.Json.JsonSerializer.Deserialize<string>(signatureJson);
-
         _Logger.LogInformation("signature : " + signatureJson);
 
-        recoverySigs ??= new SignatureInfo() { ProjectIdentifier = project.ProjectIdentifier};
-
-        recoverySigs.Signatures.Add(new SignatureInfoItem
-        {
-            Signature = signature, StageIndex = recoverySigs.Signatures.Count()
-        });
+        var res = System.Text.Json.JsonSerializer.Deserialize<SignatureInfo>(signatureJson, settings);
 
-        if (recoverySigs.Signatures.Count == project.Stages.Count())
+        if (res.ProjectIdentifier == recoverySigs.ProjectIdentifier)
         {
-            StateHasChanged();
+            recoverySigs.Signatures = res.Signatures;
         }
+
+        StateHasChanged();
     }
 
+    private JsonSerializerOptions settings => new()
+    {
+    // Equivalent to Formatting = Formatting.None
+        WriteIndented = false,
+
+    // Equivalent to NullValueHandling = NullValueHandling.Ignore
+        DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
+
+    // PropertyNamingPolicy equivalent to CamelCasePropertyNamesContractResolver
+        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+
+        Converters = { new UnixDateTimeConverter() }
+    };
+
     public async Task PublishSignedTransactionAsync()
     {
         validatingsignaturs = true;
@@ -475,7 +488,7 @@
 
         if (operationResult.Success)
         {
-            notificationComponent.ShowNotificationMessage("Invested in project", 1);
+            notificationComponent.ShowNotificationMessage("Invested in project", 5);
 
             storage.AddProject(project);
             
diff --git a/src/Angor/Server/TestNostrSigningFromRelay.cs b/src/Angor/Server/TestNostrSigningFromRelay.cs
index b07a273d..39d0f21b 100644
--- a/src/Angor/Server/TestNostrSigningFromRelay.cs
+++ b/src/Angor/Server/TestNostrSigningFromRelay.cs
@@ -142,26 +142,21 @@ private void SignInvestorTransactionsAsync(string projectIdentifier, NostrEncryp
         _clientLogger.LogInformation(transactionHex);
 
         var sig = signProject(transactionHex, project, projectKeys.founderSigningPrivateKey);
-        
-        foreach (var stage in sig.Signatures)
-        {
-            var sigJson = System.Text.Json.JsonSerializer.Serialize(stage.Signature);
 
-            _logger.LogInformation($"Signature to send for stage {stage.StageIndex}: {sigJson}");
-
-            var ev = new NostrEvent
-            {
-                Kind = NostrKind.EncryptedDm,
-                CreatedAt = DateTime.UtcNow,
-                Content = sigJson,
-                Tags = new NostrEventTags(new[] { NostrEventTag.Profile(nostrEvent.Pubkey) })
-            };
+        var sigJson = System.Text.Json.JsonSerializer.Serialize(sig, settings);
+        _logger.LogInformation($"Signature to send for stage {sig.ProjectIdentifier} : {sigJson}");
+        var ev = new NostrEvent
+        {
+            Kind = NostrKind.EncryptedDm,
+            CreatedAt = DateTime.UtcNow,
+            Content = sigJson,
+            Tags = new NostrEventTags(new[] { NostrEventTag.Profile(nostrEvent.Pubkey) })
+        };
 
-            var signed = NostrEncryptedEvent.EncryptDirectMessage(ev, nostrPrivateKey)
-                .Sign(nostrPrivateKey);
+        var signed = NostrEncryptedEvent.EncryptDirectMessage(ev, nostrPrivateKey)
+            .Sign(nostrPrivateKey);
 
-            _nostrClient.Send(new NostrEventRequest(signed));
-        }
+        _nostrClient.Send(new NostrEventRequest(signed));
     }
 
     private SignatureInfo signProject(string transactionHex,ProjectInfo info, string founderSigningPrivateKey)