-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
43d15bd
commit 02c9d13
Showing
18 changed files
with
769 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using ProjectOrigin.Stamp.Server.Repositories; | ||
|
||
namespace ProjectOrigin.Stamp.Server.Database; | ||
|
||
public interface IUnitOfWork | ||
{ | ||
void Commit(); | ||
void Rollback(); | ||
|
||
IRecipientRepository RecipientRepository { get; } | ||
} |
1 change: 0 additions & 1 deletion
1
src/ProjectOrigin.Stamp.Server/Database/Postgres/PostgresConnectionFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/ProjectOrigin.Stamp.Server/Database/Postgres/Scripts/0001.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
CREATE TABLE IF NOT EXISTS Recipients ( | ||
id uuid NOT NULL PRIMARY KEY, | ||
wallet_endpoint_reference_version integer NOT NULL, | ||
wallet_endpoint_reference_endpoint VARCHAR(512) NOT NULL, | ||
wallet_endpoint_reference_public_key bytea NOT NULL | ||
); |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
using ProjectOrigin.Stamp.Server.Repositories; | ||
|
||
namespace ProjectOrigin.Stamp.Server.Database; | ||
|
||
public class UnitOfWork : IUnitOfWork, IDisposable | ||
{ | ||
private IRecipientRepository _recipientRepository = null!; | ||
|
||
public IRecipientRepository RecipientRepository | ||
{ | ||
get | ||
{ | ||
return _recipientRepository ??= new RecipientRepository(_lazyTransaction.Value.Connection ?? throw new InvalidOperationException("Transaction is null.")); | ||
} | ||
} | ||
|
||
private readonly Dictionary<Type, object> _repositories = new Dictionary<Type, object>(); | ||
private readonly Lazy<IDbConnection> _lazyConnection; | ||
private Lazy<IDbTransaction> _lazyTransaction; | ||
private bool _disposed = false; | ||
|
||
public UnitOfWork(IDbConnectionFactory connectionFactory) | ||
{ | ||
_lazyConnection = new Lazy<IDbConnection>(() => | ||
{ | ||
var connection = connectionFactory.CreateConnection(); | ||
connection.Open(); | ||
return connection; | ||
}); | ||
|
||
_lazyTransaction = new Lazy<IDbTransaction>(_lazyConnection.Value.BeginTransaction); | ||
} | ||
|
||
public void Commit() | ||
{ | ||
if (!_lazyTransaction.IsValueCreated) | ||
return; | ||
|
||
try | ||
{ | ||
_lazyTransaction.Value.Commit(); | ||
} | ||
catch | ||
{ | ||
_lazyTransaction.Value.Rollback(); | ||
throw; | ||
} | ||
finally | ||
{ | ||
ResetUnitOfWork(); | ||
} | ||
} | ||
|
||
public void Rollback() | ||
{ | ||
if (!_lazyTransaction.IsValueCreated) | ||
return; | ||
|
||
_lazyTransaction.Value.Rollback(); | ||
|
||
ResetUnitOfWork(); | ||
} | ||
|
||
private void ResetUnitOfWork() | ||
{ | ||
if (_lazyTransaction.IsValueCreated) | ||
_lazyTransaction.Value.Dispose(); | ||
|
||
_lazyTransaction = new Lazy<IDbTransaction>(_lazyConnection.Value.BeginTransaction); | ||
|
||
_repositories.Clear(); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
~UnitOfWork() => Dispose(false); | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (disposing && !_disposed) | ||
{ | ||
_disposed = true; | ||
|
||
if (_lazyTransaction.IsValueCreated) | ||
{ | ||
_lazyTransaction.Value.Dispose(); | ||
} | ||
|
||
if (_lazyConnection.IsValueCreated) | ||
{ | ||
_lazyConnection.Value.Dispose(); | ||
} | ||
} | ||
|
||
_repositories.Clear(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
using ProjectOrigin.HierarchicalDeterministicKeys.Interfaces; | ||
|
||
namespace ProjectOrigin.Stamp.Server.Models; | ||
|
||
public class Recipient | ||
{ | ||
public required Guid Id { get; init; } | ||
public required int WalletEndpointReferenceVersion { get; init; } | ||
public required string WalletEndpointReferenceEndpoint { get; init; } | ||
public required IHDPublicKey WalletEndpointReferencePublicKey { get; init; } | ||
} |
12 changes: 12 additions & 0 deletions
12
src/ProjectOrigin.Stamp.Server/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"profiles": { | ||
"ProjectOrigin.Stamp.Server": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"applicationUrl": "https://localhost:57881;http://localhost:57882" | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/ProjectOrigin.Stamp.Server/Repositories/RecipientRepository.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System; | ||
using System.Data; | ||
using System.Threading.Tasks; | ||
using Dapper; | ||
using ProjectOrigin.Stamp.Server.Models; | ||
|
||
namespace ProjectOrigin.Stamp.Server.Repositories; | ||
|
||
public interface IRecipientRepository | ||
{ | ||
Task<int> Create(Recipient recipient); | ||
Task<Recipient?> Get(Guid id); | ||
} | ||
|
||
public class RecipientRepository : IRecipientRepository | ||
{ | ||
private readonly IDbConnection _connection; | ||
|
||
public RecipientRepository(IDbConnection connection) | ||
{ | ||
_connection = connection; | ||
} | ||
|
||
public Task<int> Create(Recipient recipient) | ||
{ | ||
return _connection.ExecuteAsync( | ||
@"INSERT INTO recipients (id, wallet_endpoint_reference_version, wallet_endpoint_reference_endpoint, wallet_endpoint_reference_public_key) | ||
VALUES (@Id, @WalletEndpointReferenceVersion, @WalletEndpointReferenceEndpoint, @WalletEndpointReferencePublicKey)", | ||
new | ||
{ | ||
recipient.Id, | ||
recipient.WalletEndpointReferenceVersion, | ||
recipient.WalletEndpointReferenceEndpoint, | ||
recipient.WalletEndpointReferencePublicKey | ||
}); | ||
} | ||
|
||
public Task<Recipient?> Get(Guid id) | ||
{ | ||
return _connection.QueryFirstOrDefaultAsync<Recipient>( | ||
@"SELECT id, wallet_endpoint_reference_version, wallet_endpoint_reference_endpoint, wallet_endpoint_reference_public_key | ||
FROM recipients | ||
WHERE id = @Id", | ||
new { Id = id }); | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
src/ProjectOrigin.Stamp.Server/Services/REST/v1/RecipientController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using System; | ||
using System.Threading.Tasks; | ||
using ProjectOrigin.Stamp.Server.Database; | ||
using ProjectOrigin.Stamp.Server.Models; | ||
using ProjectOrigin.HierarchicalDeterministicKeys.Implementations; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace ProjectOrigin.Stamp.Server.Services.REST.v1; | ||
|
||
[ApiController] | ||
public class RecipientController : ControllerBase | ||
Check warning on line 12 in src/ProjectOrigin.Stamp.Server/Services/REST/v1/RecipientController.cs GitHub Actions / analyse / sonar-analysis
|
||
{ | ||
/// <summary> | ||
/// Creates a new recipient | ||
/// </summary> | ||
/// <param name="unitOfWork"></param> | ||
/// <param name="request">The create recipient request</param> | ||
/// <response code="201">The recipient was created.</response> | ||
[HttpPost] | ||
[Route("v1/recipients")] | ||
[Produces("application/json")] | ||
[ProducesResponseType(StatusCodes.Status201Created)] | ||
public async Task<ActionResult<CreateRecipientResponse>> CreateRecipient( | ||
[FromServices] IUnitOfWork unitOfWork, | ||
[FromBody] CreateRecipientRequest request) | ||
{ | ||
var recipient = new Recipient | ||
{ | ||
Id = Guid.NewGuid(), | ||
WalletEndpointReferenceVersion = request.WalletEndpointReference.Version, | ||
WalletEndpointReferenceEndpoint = request.WalletEndpointReference.Endpoint.ToString(), | ||
WalletEndpointReferencePublicKey = new Secp256k1Algorithm().ImportHDPublicKey(request.WalletEndpointReference.PublicKey) | ||
}; | ||
|
||
await unitOfWork.RecipientRepository.Create(recipient); | ||
|
||
unitOfWork.Commit(); | ||
|
||
return Created(null as string, new CreateRecipientResponse | ||
{ | ||
Id = recipient.Id | ||
}); | ||
} | ||
} | ||
|
||
#region Records | ||
|
||
/// <summary> | ||
/// Request to create a new recipient. | ||
/// </summary> | ||
public record CreateRecipientRequest | ||
{ | ||
/// <summary> | ||
/// The recipient wallet endpoint reference. | ||
/// </summary> | ||
public required WalletEndpointReferenceDto WalletEndpointReference { get; init; } | ||
Check warning on line 57 in src/ProjectOrigin.Stamp.Server/Services/REST/v1/RecipientController.cs GitHub Actions / analyse / sonar-analysis
|
||
} | ||
|
||
public record WalletEndpointReferenceDto | ||
{ | ||
/// <summary> | ||
/// The version of the ReceiveSlice API. | ||
/// </summary> | ||
public required int Version { get; init; } | ||
Check warning on line 65 in src/ProjectOrigin.Stamp.Server/Services/REST/v1/RecipientController.cs GitHub Actions / analyse / sonar-analysis
|
||
|
||
/// <summary> | ||
/// The url endpoint of where the wallet is hosted. | ||
/// </summary> | ||
public required Uri Endpoint { get; init; } | ||
|
||
/// <summary> | ||
/// The public key used to generate sub-public-keys for each slice. | ||
/// </summary> | ||
public required byte[] PublicKey { get; init; } | ||
} | ||
|
||
/// <summary> | ||
/// Response to create a recipient. | ||
/// </summary> | ||
public record CreateRecipientResponse | ||
{ | ||
/// <summary> | ||
/// The ID of the created recipient. | ||
/// </summary> | ||
public required Guid Id { get; init; } | ||
} | ||
#endregion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/ProjectOrigin.Stamp.Test/Extensions/HttpClientExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System.Net.Http.Json; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace ProjectOrigin.Stamp.Test.Extensions; | ||
|
||
public static class HttpClientExtensions | ||
{ | ||
public static async Task<T?> ReadJson<T>(this HttpContent content) | ||
{ | ||
var options = GetJsonSerializerOptions(); | ||
return await content.ReadFromJsonAsync<T>(options); | ||
} | ||
|
||
private static JsonSerializerOptions GetJsonSerializerOptions() | ||
{ | ||
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); | ||
options.Converters.Add(new JsonStringEnumConverter()); | ||
return options; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.