From 0615ffa131d9bfa0d2da937b390860fb9da516fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20A=2EP?=
<53834183+Jossec101@users.noreply.github.com>
Date: Thu, 12 Jan 2023 14:27:36 +0100
Subject: [PATCH] Delete signer directory
---
.../FundsManagerSigner.Tests/FunctionTest.cs | 175 --------------
signer/FundsManagerSigner/Function.cs | 221 ------------------
2 files changed, 396 deletions(-)
delete mode 100644 signer/FundsManagerSigner.Tests/FunctionTest.cs
delete mode 100644 signer/FundsManagerSigner/Function.cs
diff --git a/signer/FundsManagerSigner.Tests/FunctionTest.cs b/signer/FundsManagerSigner.Tests/FunctionTest.cs
deleted file mode 100644
index ecaa85b0..00000000
--- a/signer/FundsManagerSigner.Tests/FunctionTest.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-using System.Text.Json;
-using Amazon.Lambda.APIGatewayEvents;
-using Xunit;
-using Amazon.Lambda.Core;
-using Amazon.Lambda.TestUtilities;
-using FluentAssertions;
-using NBitcoin;
-
-namespace FundsManagerSigner.Tests;
-
-public class FunctionTest : IDisposable
-{
- ///
- /// Aux method that sets the env vars for tests
- ///
- ///
- public FunctionTest()
- {
- var config = new SignPSBTConfig
- {
- AwsKmsKeyId = "mrk-cec3e3ef59bc4616a6f44da60bfea0ba",
- EncryptedSeedphrase =
- "AQICAHheBtxW+2iTBvvhvmRXaxaScHh6up1/VWCRSMlopexrdwE1C/ylXBL5pmjJ3P/UG7XnAAABBzCCAQMGCSqGSIb3DQEHBqCB9TCB8gIBADCB7AYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxPlkxPX65p7aRcXykCARCAgb4En2Bb/nWQ6m4i3JDP+KGjaGDAVF4LR6+2Ljl7orp6pfZbCCxK6e89OBpJWi7elQM670vD/SWkYSZ9MUWUshU8n7NyBJZuZgBhtaH6j6yDhgHtBv7cwJngv0d72QEaTrH2YqLCVuoddEKEpB13ezfkf56230QD134kcJze4fITQGA6sXxQ0x+WjKOeYltpB+Shk4+kaNja42ZM0MMjyrMOmQtXCkgdoTUVi6twiqU+qr8mQEEq0aNdZzlLCI/v"
- };
- var configJSon = JsonSerializer.Serialize(config);
- Environment.SetEnvironmentVariable("ed0210c8", configJSon);
- }
-
- public void Dispose()
- {
- Environment.SetEnvironmentVariable("ed0210c8", null);
- }
-
- [Fact]
- public async Task SignTest()
- {
- //Arrange
- var function = new Function();
- var context = new TestLambdaContext();
-
- //Test PSBT with 1 partial sig on input 0
- //JSON
- //{ "Psbt":"cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15\u002B6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP\u002BhqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po\u002BBAlGvFeBbuLfqwYlbP19H/\u002B/s2DIaAu8iKY\u002BJ0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6\u002BzUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn\u002B/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS\u002Bn7AgEDBAIAAAABBWlSIQLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI\u002BWNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF\u002BN0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==","Fingerprint":"ed0210c8","AccountDerivationPath":"m/48\u0027/1\u0027/1\u0027","AddressDerivationPath":"0/0","EnforcedSighash":1,"Network":"Regtest","AwsKmsKeyId":"mrk-cec3e3ef59bc4616a6f44da60bfea0ba"}
- var input = new SignPSBTRequest(
- "cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15+6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP+hqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po+BAlGvFeBbuLfqwYlbP19H/+/s2DIaAu8iKY+J0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6+zUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn+/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS+n7AgEDBAIAAAABBWlSIQLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI+WNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF+N0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==",
- SigHash.All,
- "Regtest");
-
- var initialPSBT = PSBT.Parse(input.Psbt, Network.RegTest);
-
- var inputJson = JsonSerializer.Serialize(input);
-
- var request = new APIGatewayHttpApiV2ProxyRequest
- {
- Body = inputJson
- };
- //Act
- var result = await function.FunctionHandler(request, context);
-
- var responseBody = JsonSerializer.Deserialize(result.Body);
-
- var parsedPSBT = PSBT.Parse(responseBody.Psbt ?? throw new InvalidOperationException(), Network.RegTest);
-
- //Assert
- responseBody.Should().NotBeNull();
- parsedPSBT.Inputs.All(x => x.PartialSigs.Count > initialPSBT.Inputs[(int) x.Index].PartialSigs.Count).Should().BeTrue();
- parsedPSBT.Inputs.All(x => x.SighashType == input.EnforcedSighash).Should().BeTrue();
- }
-
- [Fact]
- public async Task FailedSignTest_InvalidDerivationPath()
- {
- //Arrange
- var function = new Function();
- var context = new TestLambdaContext();
-
- //Test PSBT with 1 partial sig on input 0
- //JSON
- //{ "Psbt":"cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15\u002B6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP\u002BhqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po\u002BBAlGvFeBbuLfqwYlbP19H/\u002B/s2DIaAu8iKY\u002BJ0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6\u002BzUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn\u002B/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS\u002Bn7AgEDBAIAAAABBWlSIQLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI\u002BWNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF\u002BN0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==","Fingerprint":"ed0210c8","AccountDerivationPath":"m/48\u0027/1\u0027/1\u0027","AddressDerivationPath":"0/0","EnforcedSighash":1,"Network":"Regtest","AwsKmsKeyId":"mrk-cec3e3ef59bc4616a6f44da60bfea0ba"}
- var psbtBase64 = "cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15+6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP+hqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po+BAlGvFeBbuLfqwYlbP19H/+/s2DIaAu8iKY+J0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6+zUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn+/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS+n7AgEDBAIAAAABBWlSIQLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI+WNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF+N0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==";
-
- var psbt = PSBT.Parse(psbtBase64, Network.RegTest);
-
- foreach (var psbtInput in psbt.Inputs)
- {
- var temp = psbtInput.HDKeyPaths;
- psbtInput.HDKeyPaths.Clear(); ;
- foreach (var rootedKeyPath in temp)
- {
- psbtInput.AddKeyPath(rootedKeyPath.Key, new RootedKeyPath(rootedKeyPath.Value.MasterFingerprint, new KeyPath("m/48'")));
- }
- }
-
- var input = new SignPSBTRequest(
- psbt.ToBase64(),
- SigHash.All,
- "Regtest");
-
- var inputJson = JsonSerializer.Serialize(input);
-
- var request = new APIGatewayHttpApiV2ProxyRequest
- {
- Body = inputJson
- };
- //Act
- var result = await function.FunctionHandler(request, context);
-
- //Assert
- result.StatusCode.Should().Be(500);
- result.Body.Should().Contain("derivation");
- }
-
- [Fact]
- public async Task FailedSignTest_NoAddedPartialSig()
- {
- //Arrange
- var function = new Function();
- var context = new TestLambdaContext();
-
- //Test PSBT with 1 partial sig on input 0
- //JSON
- //{ "Psbt":"cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15\u002B6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP\u002BhqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po\u002BBAlGvFeBbuLfqwYlbP19H/\u002B/s2DIaAu8iKY\u002BJ0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6\u002BzUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn\u002B/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS\u002Bn7AgEDBAIAAAABBWlSIQLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz\u002BbATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI\u002BWNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF\u002BN0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==","Fingerprint":"ed0210c8","AccountDerivationPath":"m/48\u0027/1\u0027/1\u0027","AddressDerivationPath":"0/0","EnforcedSighash":1,"Network":"Regtest","AwsKmsKeyId":"mrk-cec3e3ef59bc4616a6f44da60bfea0ba"}
- var psbtBase64 = "cHNidP8BAF4BAAAAAWAvqvtTSjdcNjNuK8YKWQg7RM1S8LFDdIXg3KU34l6/AQAAAAD/////AYSRNXcAAAAAIgAguNLINpkV//IIFd1ti2ig15+6mPOhNWykV0mwsneO9FcAAAAATwEENYfPAy8RJCyAAAAB/DvuQjoBjOttImoGYyiO0Pte4PqdeQqzcNAw4Ecw5sgDgI4uHNSCvdBxlpQ8WoEz0WmvhgIra7A4F3FkTsB0RNcQH8zk3jAAAIABAACAAQAAgE8BBDWHzwNWrAP0gAAAAfkIrkpmsP+hqxS1WvDOSPKnAiXLkBCQLWkBr5C5Po+BAlGvFeBbuLfqwYlbP19H/+/s2DIaAu8iKY+J0KIDffBgEGDzoLMwAACAAQAAgAEAAIBPAQQ1h88DfblGjYAAAAH1InDHaHo6+zUe9PG5owwQ87bTkhcGg66pSIwTmhHJmAMiI4UjOOpn+/2Nw1KrJiXnmid2RiEja/HAITCQ00ienxDtAhDIMAAAgAEAAIABAACAAAEBKwCUNXcAAAAAIgAgs1MYpDJWIIGz/LeRwb5D/c1wgjKmSotvf8QyY3nsEMQiAgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssUcwRAIgKsJYoVeZWSHLhJIIELCGqDZXBWF2JcYFgYUbTSg31gYCIAbh5LXC9mmOKmqjB3kW3rgBbHrht4B3Vz5jDXmrS+n7AgEDBAIAAAABBWlSIQLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssSEDAmf/CxGXSG9xiPljcG/e5CXFnnukFn0pJ64Q9U2aNL8hAxpTd/JawX43QWk3yFK6wOPpsRK931hHnT2R2BYwsouPU64iBgLYVMVgz+bATgvrRDQbanlASVXtiUwPt9yCgkQfv2kssRgfzOTeMAAAgAEAAIABAACAAAAAAAAAAAAiBgMCZ/8LEZdIb3GI+WNwb97kJcWee6QWfSknrhD1TZo0vxhg86CzMAAAgAEAAIABAACAAAAAAAAAAAAiBgMaU3fyWsF+N0FpN8hSusDj6bESvd9YR509kdgWMLKLjxjtAhDIMAAAgAEAAIABAACAAAAAAAAAAAAAAA==";
-
- var psbt = PSBT.Parse(psbtBase64, Network.RegTest);
-
- foreach (var psbtInput in psbt.Inputs)
- {
- var temp = psbtInput.HDKeyPaths.ToList();
- psbtInput.HDKeyPaths.Clear(); ;
- foreach (var rootedKeyPath in temp)
- {
- psbtInput.AddKeyPath(rootedKeyPath.Key, new RootedKeyPath(rootedKeyPath.Value.MasterFingerprint, new KeyPath("m/48'")));
- }
- }
-
- var input = new SignPSBTRequest(
- psbt.ToBase64(),
- SigHash.All,
- "Regtest");
-
- var inputJson = JsonSerializer.Serialize(input);
-
- var request = new APIGatewayHttpApiV2ProxyRequest
- {
- Body = inputJson
- };
- //Act
- var result = await function.FunctionHandler(request, context);
-
- //Assert
- result.StatusCode.Should().Be(500);
- result.Body.Should().Contain("partial");
- }
-
- [Fact]
- public async Task GenerateEncryptedSeedTest()
- {
- //Arrange
- var function = new Function();
- var context = new TestLambdaContext();
-
- var mnemonicString =
- "middle teach digital prefer fiscal theory syrup enter crash muffin easily anxiety ill barely eagle swim volume consider dynamic unaware deputy middle into physical";
-
- var keyId = "mrk-cec3e3ef59bc4616a6f44da60bfea0ba";
- //Act
- var result = await function.EncryptSeedphrase(mnemonicString, keyId);
- var base64Decoding = Convert.FromBase64String(result);
- //Assert
- result.Should().NotBeEmpty();
-
- base64Decoding.Should().NotBeEmpty();
- }
-}
\ No newline at end of file
diff --git a/signer/FundsManagerSigner/Function.cs b/signer/FundsManagerSigner/Function.cs
deleted file mode 100644
index a199216f..00000000
--- a/signer/FundsManagerSigner/Function.cs
+++ /dev/null
@@ -1,221 +0,0 @@
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Amazon.KeyManagementService;
-using Amazon.KeyManagementService.Model;
-using Amazon.Lambda.APIGatewayEvents;
-using Amazon.Lambda.Core;
-using Amazon.Lambda.Serialization.SystemTextJson;
-using NBitcoin;
-
-[assembly:
- LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer))]
-
-namespace FundsManagerSigner;
-
-[JsonSerializable(typeof(APIGatewayHttpApiV2ProxyRequest))]
-[JsonSerializable(typeof(APIGatewayHttpApiV2ProxyResponse))]
-public partial class HttpApiJsonSerializerContext : JsonSerializerContext
-{
-}
-
-///
-/// DTO used to deserialize the env var value which key is a master fingerprint of the PSBT
-///
-public class SignPSBTConfig
-{
- ///
- /// Encrypted seed phrase
- ///
- public string EncryptedSeedphrase { get; set; }
-
- ///
- /// AWS KMS Key Id used to decrypt the encrypted seedphrase
- ///
- public string AwsKmsKeyId { get; set; }
-}
-
-public class Function
-{
- ///
- /// A lambda function that takes a psbt and signs it
- ///
- ///
- ///
- ///
- public async Task FunctionHandler(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context)
- {
- var response = new APIGatewayHttpApiV2ProxyResponse();
-
- try
- {
- var requestBody = JsonSerializer.Deserialize(request.Body);
- if (requestBody == null) throw new ArgumentNullException(nameof(requestBody), "Request body not found");
-
- var kmsClient = new AmazonKeyManagementServiceClient();
-
- var network = requestBody.Network.ToUpper() switch
- {
- "REGTEST" => Network.RegTest,
- "MAINNET" => Network.Main,
- "TESTNET" => Network.TestNet,
- _ => throw new ArgumentException("Network not recognized")
- };
-
- var result = new SignPSBTResponse(null);
-
- if (PSBT.TryParse(requestBody.Psbt, network, out var parsedPSBT))
- {
- foreach (var psbtInput in parsedPSBT.Inputs)
- {
- //We search for a fingerprint that can be used as a key for getting the config (env-var)
- //Ideally, only fingerprints of the FundsManager signer wallet are set as env vars
- var derivationPath = psbtInput.HDKeyPaths.Values.SingleOrDefault(x =>
- Environment.GetEnvironmentVariable($"MF_{x.MasterFingerprint.ToString()}") != null);
-
- if (derivationPath == null)
- {
- throw new ArgumentException(
- "Invalid PSBT, the derivation path and the signing configuration cannot be found for none of the master fingerprints of all the pub keys",
- nameof(derivationPath));
- }
-
- var inputPSBTMasterFingerPrint = derivationPath.MasterFingerprint;
-
- var masterFingerPrint = $"MF_{inputPSBTMasterFingerPrint}";
- var configJson = Environment.GetEnvironmentVariable(masterFingerPrint);
-
- var config = JsonSerializer.Deserialize(configJson);
-
- var decryptedSeed = await kmsClient.DecryptAsync(new DecryptRequest
- {
- CiphertextBlob = new MemoryStream(Convert.FromBase64String(config.EncryptedSeedphrase)),
- EncryptionAlgorithm = EncryptionAlgorithmSpec.SYMMETRIC_DEFAULT,
- KeyId = config.AwsKmsKeyId
- });
-
- if (decryptedSeed == null)
- {
- throw new ArgumentException("The seedphrase could not be decrypted / found", nameof(decryptedSeed));
- }
-
- var array = decryptedSeed.Plaintext.ToArray();
-
- //The seedphrase words were originally splitted with @ instead of whitespaces due to AWS removing them on encryption
- var seed = Encoding.UTF8.GetString(array).Replace("@", " ");
-
- var extKey = new Mnemonic(seed).DeriveExtKey();
- var bitcoinExtKey = extKey.GetWif(network);
-
- var fingerPrint = bitcoinExtKey.GetPublicKey().GetHDFingerPrint();
-
- if (fingerPrint != inputPSBTMasterFingerPrint)
- {
- var mismatchingFingerprint =
- $"The master fingerprint from the input does not match the master fingerprint from the encrypted seedphrase master fingerprint";
-
- throw new ArgumentException(mismatchingFingerprint, nameof(fingerPrint));
- }
-
- var partialSigsCount = parsedPSBT.Inputs.Sum(x => x.PartialSigs.Count);
- //We can enforce the sighash for all the inputs in the request in case the PSBT was not modified or serialized correctly.
- if (requestBody.EnforcedSighash != null)
- {
- psbtInput.SighashType = requestBody.EnforcedSighash;
-
- Console.WriteLine($"Enforced sighash: {psbtInput.SighashType:G}");
- }
-
- var key = bitcoinExtKey
- .Derive(derivationPath.KeyPath)
- .PrivateKey;
- psbtInput.Sign(key);
-
- //We check that the partial signatures number has changed, otherwise finalize inmediately
- var partialSigsCountAfterSignature =
- parsedPSBT.Inputs.Sum(x => x.PartialSigs.Count);
-
- if (partialSigsCountAfterSignature == 0 ||
- partialSigsCountAfterSignature <= partialSigsCount)
- {
- var invalidNoOfPartialSignatures =
- $"Invalid expected number of partial signatures after signing the PSBT";
-
- throw new ArgumentException(
- invalidNoOfPartialSignatures);
- }
-
- result = new SignPSBTResponse(parsedPSBT.ToBase64());
-
- response = new APIGatewayHttpApiV2ProxyResponse()
- {
- Body = JsonSerializer.Serialize(result),
- IsBase64Encoded = false,
- StatusCode = 200
- };
- }
- }
- Console.WriteLine($"Signing request finished");
- }
- catch (Exception e)
- {
- await Console.Error.WriteLineAsync(e.Message);
- response = new APIGatewayHttpApiV2ProxyResponse
- {
- Body = e.Message,
- IsBase64Encoded = false,
- StatusCode = 500
- };
- }
-
- return response;
- }
-
- ///
- /// Aux method used to generate an encrypted seed, it is added for generating new ones with a unit test
- ///
- ///
- ///
- /// Base64 encrypted seedphrase
- public async Task EncryptSeedphrase(string mnemonicString, string keyId)
- {
- if (string.IsNullOrWhiteSpace(mnemonicString))
- throw new ArgumentException("Value cannot be null or whitespace.", nameof(mnemonicString));
- if (string.IsNullOrWhiteSpace(keyId))
- throw new ArgumentException("Value cannot be null or whitespace.", nameof(keyId));
-
- try
- {
- var mnemonic = new Mnemonic(mnemonicString);
- }
- catch (Exception e)
- {
- const string invalidMnemonicItContainsWhitespaces = "Invalid mnemonic";
-
- await Console.Error.WriteLineAsync(invalidMnemonicItContainsWhitespaces);
-
- await Console.Error.WriteLineAsync(e.Message);
-
- throw;
- }
-
- var kmsClient = new AmazonKeyManagementServiceClient();
-
- //To avoid KMS removing whitespaces and dismantling the seedphrase
- mnemonicString = mnemonicString.Replace(" ", "@");
-
- var encryptedSeed = await kmsClient.EncryptAsync(new EncryptRequest
- {
- EncryptionAlgorithm = EncryptionAlgorithmSpec.SYMMETRIC_DEFAULT,
- Plaintext = new MemoryStream(Encoding.UTF8.GetBytes(mnemonicString)), //UTF8 Encoding
- KeyId = keyId
- });
-
- var encryptedSeedBase64 = Convert.ToBase64String(encryptedSeed.CiphertextBlob.ToArray());
-
- return encryptedSeedBase64;
- }
-}
-
-public record SignPSBTRequest(string Psbt, SigHash? EnforcedSighash, string Network);
-public record SignPSBTResponse(string? Psbt);
\ No newline at end of file