diff --git a/.github/workflows/station.yml b/.github/workflows/station.yml
new file mode 100644
index 0000000..acffcfe
--- /dev/null
+++ b/.github/workflows/station.yml
@@ -0,0 +1,66 @@
+name: API
+
+on:
+ push:
+ branches: [ main, dev ]
+ paths:
+ - 'TrainStation/**'
+ - '.github/workflows/station.yml'
+ pull_request:
+ branches: [ main, dev ]
+ paths:
+ - 'TrainStation/**'
+ - '.github/workflows/station.yml'
+ release:
+ types: [published, created]
+
+env:
+ DOCKER_IMAGE: trainprotocol/station
+ DOTNET_VERSION: 9
+
+jobs:
+ build-and-push:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Format version
+ id: format_version
+ run: |
+ commitHash=${GITHUB_SHA:0:7}
+ ts=$(date +%s)
+ version=$commitHash-$ts
+ echo "VERSION=$version" >> $GITHUB_ENV
+
+ - name: Sanitize branch name
+ id: sanitize_branch_name
+ run: |
+ sanitized_ref_name=$(echo "${GITHUB_REF_NAME}" | sed 's/[\/.]/-/g')
+ echo "SANITIZED_REF_NAME=$sanitized_ref_name" >> $GITHUB_ENV
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Login to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: TrainStation/Dockerfile
+ push: ${{github.ref_name == 'main' || github.ref_name == 'dev'}}
+ build-args: |
+ DOTNET_VERSION=${{ env.DOTNET_VERSION }}
+ tags: |
+ ${{ env.DOCKER_IMAGE }}:${{ env.SANITIZED_REF_NAME }}-${{ env.VERSION }}
+ ${{ env.DOCKER_IMAGE }}:${{ env.SANITIZED_REF_NAME }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
\ No newline at end of file
diff --git a/TrainStation.sln b/TrainStation.sln
index e1cdf5a..e4de273 100644
--- a/TrainStation.sln
+++ b/TrainStation.sln
@@ -5,6 +5,11 @@ VisualStudioVersion = 17.13.35825.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "TrainStation\API.csproj", "{2CBBA91C-0E98-44EC-8417-5C2E686F9431}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_config", "_config", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
+ ProjectSection(SolutionItems) = preProject
+ .gitignore = .gitignore
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/TrainStation/API.csproj b/TrainStation/API.csproj
index 9a08a1a..a1bc221 100644
--- a/TrainStation/API.csproj
+++ b/TrainStation/API.csproj
@@ -12,17 +12,17 @@
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
-
-
-
-
-
-
+
diff --git a/TrainStation/Client/QuoteWithSolverDto.cs b/TrainStation/Client/QuoteWithSolverDto.cs
new file mode 100644
index 0000000..e50f842
--- /dev/null
+++ b/TrainStation/Client/QuoteWithSolverDto.cs
@@ -0,0 +1,9 @@
+using Newtonsoft.Json;
+
+namespace Train.Station.Client;
+
+public partial class QuoteWithSolverDto
+{
+ [JsonProperty("solverName", NullValueHandling = NullValueHandling.Ignore)]
+ public string SolverName { get; set; }
+}
\ No newline at end of file
diff --git a/TrainStation/Client/TrainSolverApiClient.cs b/TrainStation/Client/TrainSolverApiClient.cs
index 6b96534..8fa77e1 100644
--- a/TrainStation/Client/TrainSolverApiClient.cs
+++ b/TrainStation/Client/TrainSolverApiClient.cs
@@ -28,11 +28,6 @@ namespace Train.Station.Client
public partial interface ITrainSolverApiClient
{
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- System.Threading.Tasks.Task NetworksAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
-
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
@@ -41,32 +36,17 @@ public partial interface ITrainSolverApiClient
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- System.Threading.Tasks.Task SourcesAsync(string destinationNetwork = null, string destinationToken = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- System.Threading.Tasks.Task DestinationsAsync(string sourceNetwork = null, string sourceToken = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+ System.Threading.Tasks.Task QuoteAsync(string amount, string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- System.Threading.Tasks.Task LimitsAsync(string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+ System.Threading.Tasks.Task SwapsAsync(string commitId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- System.Threading.Tasks.Task QuoteAsync(double amount, string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- System.Threading.Tasks.Task SwapsAsync(System.Collections.Generic.IEnumerable addresses = null, int? page = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- System.Threading.Tasks.Task Swaps2Async(string commitId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+ System.Threading.Tasks.Task BuildAsync(PrepareTransactionRequest body, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
@@ -128,77 +108,6 @@ public string BaseUrl
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- public virtual async System.Threading.Tasks.Task NetworksAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
- {
- var client_ = _httpClient;
- var disposeClient_ = false;
- try
- {
- using (var request_ = new System.Net.Http.HttpRequestMessage())
- {
- request_.Method = new System.Net.Http.HttpMethod("GET");
- request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
-
- var urlBuilder_ = new System.Text.StringBuilder();
- if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/networks"
- urlBuilder_.Append("api/v1/networks");
-
- PrepareRequest(client_, request_, urlBuilder_);
-
- var url_ = urlBuilder_.ToString();
- request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
-
- PrepareRequest(client_, request_, url_);
-
- var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- var disposeResponse_ = true;
- try
- {
- var headers_ = new System.Collections.Generic.Dictionary>();
- foreach (var item_ in response_.Headers)
- headers_[item_.Key] = item_.Value;
- if (response_.Content != null && response_.Content.Headers != null)
- {
- foreach (var item_ in response_.Content.Headers)
- headers_[item_.Key] = item_.Value;
- }
-
- ProcessResponse(client_, response_);
-
- var status_ = (int)response_.StatusCode;
- if (status_ == 200)
- {
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
- if (objectResponse_.Object == null)
- {
- throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
- }
- return objectResponse_.Object;
- }
- else
- {
- var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
- throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
- }
- }
- finally
- {
- if (disposeResponse_)
- response_.Dispose();
- }
- }
- }
- finally
- {
- if (disposeClient_)
- client_.Dispose();
- }
- }
-
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
@@ -273,258 +182,7 @@ public string BaseUrl
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- public virtual async System.Threading.Tasks.Task SourcesAsync(string destinationNetwork = null, string destinationToken = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
- {
- var client_ = _httpClient;
- var disposeClient_ = false;
- try
- {
- using (var request_ = new System.Net.Http.HttpRequestMessage())
- {
- request_.Method = new System.Net.Http.HttpMethod("GET");
- request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
-
- var urlBuilder_ = new System.Text.StringBuilder();
- if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/sources"
- urlBuilder_.Append("api/v1/sources");
- urlBuilder_.Append('?');
- if (destinationNetwork != null)
- {
- urlBuilder_.Append(System.Uri.EscapeDataString("destinationNetwork")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(destinationNetwork, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- }
- if (destinationToken != null)
- {
- urlBuilder_.Append(System.Uri.EscapeDataString("destinationToken")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(destinationToken, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- }
- urlBuilder_.Length--;
-
- PrepareRequest(client_, request_, urlBuilder_);
-
- var url_ = urlBuilder_.ToString();
- request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
-
- PrepareRequest(client_, request_, url_);
-
- var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- var disposeResponse_ = true;
- try
- {
- var headers_ = new System.Collections.Generic.Dictionary>();
- foreach (var item_ in response_.Headers)
- headers_[item_.Key] = item_.Value;
- if (response_.Content != null && response_.Content.Headers != null)
- {
- foreach (var item_ in response_.Content.Headers)
- headers_[item_.Key] = item_.Value;
- }
-
- ProcessResponse(client_, response_);
-
- var status_ = (int)response_.StatusCode;
- if (status_ == 200)
- {
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
- if (objectResponse_.Object == null)
- {
- throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
- }
- return objectResponse_.Object;
- }
- else
- {
- var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
- throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
- }
- }
- finally
- {
- if (disposeResponse_)
- response_.Dispose();
- }
- }
- }
- finally
- {
- if (disposeClient_)
- client_.Dispose();
- }
- }
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- public virtual async System.Threading.Tasks.Task DestinationsAsync(string sourceNetwork = null, string sourceToken = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
- {
- var client_ = _httpClient;
- var disposeClient_ = false;
- try
- {
- using (var request_ = new System.Net.Http.HttpRequestMessage())
- {
- request_.Method = new System.Net.Http.HttpMethod("GET");
- request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
-
- var urlBuilder_ = new System.Text.StringBuilder();
- if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/destinations"
- urlBuilder_.Append("api/v1/destinations");
- urlBuilder_.Append('?');
- if (sourceNetwork != null)
- {
- urlBuilder_.Append(System.Uri.EscapeDataString("sourceNetwork")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(sourceNetwork, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- }
- if (sourceToken != null)
- {
- urlBuilder_.Append(System.Uri.EscapeDataString("sourceToken")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(sourceToken, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- }
- urlBuilder_.Length--;
-
- PrepareRequest(client_, request_, urlBuilder_);
-
- var url_ = urlBuilder_.ToString();
- request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
-
- PrepareRequest(client_, request_, url_);
-
- var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- var disposeResponse_ = true;
- try
- {
- var headers_ = new System.Collections.Generic.Dictionary>();
- foreach (var item_ in response_.Headers)
- headers_[item_.Key] = item_.Value;
- if (response_.Content != null && response_.Content.Headers != null)
- {
- foreach (var item_ in response_.Content.Headers)
- headers_[item_.Key] = item_.Value;
- }
-
- ProcessResponse(client_, response_);
-
- var status_ = (int)response_.StatusCode;
- if (status_ == 200)
- {
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
- if (objectResponse_.Object == null)
- {
- throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
- }
- return objectResponse_.Object;
- }
- else
- {
- var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
- throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
- }
- }
- finally
- {
- if (disposeResponse_)
- response_.Dispose();
- }
- }
- }
- finally
- {
- if (disposeClient_)
- client_.Dispose();
- }
- }
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- public virtual async System.Threading.Tasks.Task LimitsAsync(string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
- {
- if (sourceNetwork == null)
- throw new System.ArgumentNullException("sourceNetwork");
-
- if (sourceToken == null)
- throw new System.ArgumentNullException("sourceToken");
-
- if (destinationNetwork == null)
- throw new System.ArgumentNullException("destinationNetwork");
-
- if (destinationToken == null)
- throw new System.ArgumentNullException("destinationToken");
-
- var client_ = _httpClient;
- var disposeClient_ = false;
- try
- {
- using (var request_ = new System.Net.Http.HttpRequestMessage())
- {
- request_.Method = new System.Net.Http.HttpMethod("GET");
- request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
-
- var urlBuilder_ = new System.Text.StringBuilder();
- if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/limits"
- urlBuilder_.Append("api/v1/limits");
- urlBuilder_.Append('?');
- urlBuilder_.Append(System.Uri.EscapeDataString("SourceNetwork")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(sourceNetwork, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- urlBuilder_.Append(System.Uri.EscapeDataString("SourceToken")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(sourceToken, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- urlBuilder_.Append(System.Uri.EscapeDataString("DestinationNetwork")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(destinationNetwork, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- urlBuilder_.Append(System.Uri.EscapeDataString("DestinationToken")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(destinationToken, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- urlBuilder_.Length--;
-
- PrepareRequest(client_, request_, urlBuilder_);
-
- var url_ = urlBuilder_.ToString();
- request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
-
- PrepareRequest(client_, request_, url_);
-
- var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
- var disposeResponse_ = true;
- try
- {
- var headers_ = new System.Collections.Generic.Dictionary>();
- foreach (var item_ in response_.Headers)
- headers_[item_.Key] = item_.Value;
- if (response_.Content != null && response_.Content.Headers != null)
- {
- foreach (var item_ in response_.Content.Headers)
- headers_[item_.Key] = item_.Value;
- }
-
- ProcessResponse(client_, response_);
-
- var status_ = (int)response_.StatusCode;
- if (status_ == 200)
- {
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
- if (objectResponse_.Object == null)
- {
- throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
- }
- return objectResponse_.Object;
- }
- else
- {
- var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
- throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
- }
- }
- finally
- {
- if (disposeResponse_)
- response_.Dispose();
- }
- }
- }
- finally
- {
- if (disposeClient_)
- client_.Dispose();
- }
- }
-
- /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
- /// OK
- /// A server side error occurred.
- public virtual async System.Threading.Tasks.Task QuoteAsync(double amount, string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
+ public virtual async System.Threading.Tasks.Task QuoteAsync(string amount, string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
if (amount == null)
throw new System.ArgumentNullException("amount");
@@ -587,7 +245,7 @@ public string BaseUrl
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
@@ -617,8 +275,11 @@ public string BaseUrl
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- public virtual async System.Threading.Tasks.Task SwapsAsync(System.Collections.Generic.IEnumerable addresses = null, int? page = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
+ public virtual async System.Threading.Tasks.Task SwapsAsync(string commitId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
+ if (commitId == null)
+ throw new System.ArgumentNullException("commitId");
+
var client_ = _httpClient;
var disposeClient_ = false;
try
@@ -630,18 +291,9 @@ public string BaseUrl
var urlBuilder_ = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/swaps"
- urlBuilder_.Append("api/v1/swaps");
- urlBuilder_.Append('?');
- if (addresses != null)
- {
- foreach (var item_ in addresses) { urlBuilder_.Append(System.Uri.EscapeDataString("addresses")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); }
- }
- if (page != null)
- {
- urlBuilder_.Append(System.Uri.EscapeDataString("page")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(page, System.Globalization.CultureInfo.InvariantCulture))).Append('&');
- }
- urlBuilder_.Length--;
+ // Operation Path: "api/v1/swaps/{commitId}"
+ urlBuilder_.Append("api/v1/swaps/");
+ urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(commitId, System.Globalization.CultureInfo.InvariantCulture)));
PrepareRequest(client_, request_, urlBuilder_);
@@ -698,10 +350,10 @@ public string BaseUrl
/// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
/// OK
/// A server side error occurred.
- public virtual async System.Threading.Tasks.Task Swaps2Async(string commitId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
+ public virtual async System.Threading.Tasks.Task BuildAsync(PrepareTransactionRequest body, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
- if (commitId == null)
- throw new System.ArgumentNullException("commitId");
+ if (body == null)
+ throw new System.ArgumentNullException("body");
var client_ = _httpClient;
var disposeClient_ = false;
@@ -709,14 +361,17 @@ public string BaseUrl
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
- request_.Method = new System.Net.Http.HttpMethod("GET");
+ var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, JsonSerializerSettings);
+ var content_ = new System.Net.Http.StringContent(json_);
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
var urlBuilder_ = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
- // Operation Path: "api/v1/swaps/{commitId}"
- urlBuilder_.Append("api/v1/swaps/");
- urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(commitId, System.Globalization.CultureInfo.InvariantCulture)));
+ // Operation Path: "api/v1/transactions/build"
+ urlBuilder_.Append("api/v1/transactions/build");
PrepareRequest(client_, request_, urlBuilder_);
@@ -743,7 +398,7 @@ public string BaseUrl
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
- var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
@@ -1030,18 +685,6 @@ private string ConvertToString(object value, System.Globalization.CultureInfo cu
}
}
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public enum AccountType
- {
-
- [System.Runtime.Serialization.EnumMember(Value = @"LP")]
- LP = 0,
-
- [System.Runtime.Serialization.EnumMember(Value = @"Charging")]
- Charging = 1,
-
- }
-
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class AddLockSignatureModel
{
@@ -1068,9 +711,6 @@ public partial class AddLockSignatureModel
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class ApiError
{
- [Newtonsoft.Json.JsonProperty("code", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Code { get; set; }
-
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Message { get; set; }
@@ -1085,46 +725,35 @@ public partial class ApiResponse
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ApiResponseLimitDto
- {
- [Newtonsoft.Json.JsonProperty("error", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public ApiError Error { get; set; }
-
- [Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public LimitDto Data { get; set; }
-
- }
-
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ApiResponseListDetailedNetworkDto
+ public partial class ApiResponseListRouteDto
{
[Newtonsoft.Json.JsonProperty("error", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public ApiError Error { get; set; }
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection Data { get; set; }
+ public System.Collections.Generic.ICollection Data { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ApiResponseListRouteDto
+ public partial class ApiResponsePrepareTransactionDto
{
[Newtonsoft.Json.JsonProperty("error", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public ApiError Error { get; set; }
- [Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection Data { get; set; }
+ [Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public PrepareTransactionDto Data { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ApiResponseQuoteDto
+ public partial class ApiResponseQuoteWithSolverDto
{
[Newtonsoft.Json.JsonProperty("error", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public ApiError Error { get; set; }
[Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public QuoteDto Data { get; set; }
+ public QuoteWithSolverDto Data { get; set; }
}
@@ -1140,211 +769,115 @@ public partial class ApiResponseSwapDto
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public enum ContarctType
- {
-
- [System.Runtime.Serialization.EnumMember(Value = @"HTLCNativeContractAddress")]
- HTLCNativeContractAddress = 0,
-
- [System.Runtime.Serialization.EnumMember(Value = @"HTLCTokenContractAddress")]
- HTLCTokenContractAddress = 1,
-
- [System.Runtime.Serialization.EnumMember(Value = @"GasPriceOracleContract")]
- GasPriceOracleContract = 2,
-
- [System.Runtime.Serialization.EnumMember(Value = @"EvmMultiCallContract")]
- EvmMultiCallContract = 3,
-
- }
-
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ContractDto
- {
- [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
- public ContarctType Type { get; set; }
-
- [Newtonsoft.Json.JsonProperty("address", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Address { get; set; }
-
- }
-
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class DetailedNetworkDto
+ public partial class NetworkDto
{
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Name { get; set; }
- [Newtonsoft.Json.JsonProperty("chainId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ [Newtonsoft.Json.JsonProperty("chainId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string ChainId { get; set; }
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public NetworkType Type { get; set; }
- [Newtonsoft.Json.JsonProperty("displayName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string DisplayName { get; set; }
-
- [Newtonsoft.Json.JsonProperty("logo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Logo { get; set; }
-
- [Newtonsoft.Json.JsonProperty("transactionExplorerTemplate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string TransactionExplorerTemplate { get; set; }
-
- [Newtonsoft.Json.JsonProperty("accountExplorerTemplate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string AccountExplorerTemplate { get; set; }
-
- [Newtonsoft.Json.JsonProperty("nativeToken", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public DetailedTokenDto NativeToken { get; set; }
-
- [Newtonsoft.Json.JsonProperty("tokens", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection Tokens { get; set; }
-
- [Newtonsoft.Json.JsonProperty("nodes", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection Nodes { get; set; }
-
- [Newtonsoft.Json.JsonProperty("contracts", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection Contracts { get; set; }
-
- [Newtonsoft.Json.JsonProperty("managedAccounts", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public System.Collections.Generic.ICollection ManagedAccounts { get; set; }
-
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class DetailedTokenDto
+ public enum NetworkType
{
- [Newtonsoft.Json.JsonProperty("symbol", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Symbol { get; set; }
- [Newtonsoft.Json.JsonProperty("contract", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Contract { get; set; }
+ [System.Runtime.Serialization.EnumMember(Value = @"EVM")]
+ EVM = 0,
- [Newtonsoft.Json.JsonProperty("decimals", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public int Decimals { get; set; }
+ [System.Runtime.Serialization.EnumMember(Value = @"Solana")]
+ Solana = 1,
- [Newtonsoft.Json.JsonProperty("precision", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public int Precision { get; set; }
+ [System.Runtime.Serialization.EnumMember(Value = @"Starknet")]
+ Starknet = 2,
- [Newtonsoft.Json.JsonProperty("logo", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Logo { get; set; }
+ [System.Runtime.Serialization.EnumMember(Value = @"Fuel")]
+ Fuel = 3,
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class LimitDto
+ public partial class PrepareTransactionDto
{
- [Newtonsoft.Json.JsonProperty("minAmountInUsd", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double MinAmountInUsd { get; set; }
-
- [Newtonsoft.Json.JsonProperty("minAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double MinAmount { get; set; }
+ [Newtonsoft.Json.JsonProperty("toAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ToAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("maxAmountInUsd", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double MaxAmountInUsd { get; set; }
+ [Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Data { get; set; }
- [Newtonsoft.Json.JsonProperty("maxAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double MaxAmount { get; set; }
+ [Newtonsoft.Json.JsonProperty("asset", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Asset { get; set; }
- }
+ [Newtonsoft.Json.JsonProperty("amount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Amount { get; set; }
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class ManagedAccountDto
- {
- [Newtonsoft.Json.JsonProperty("address", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Address { get; set; }
+ [Newtonsoft.Json.JsonProperty("callDataAsset", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string CallDataAsset { get; set; }
- [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
- public AccountType Type { get; set; }
+ [Newtonsoft.Json.JsonProperty("callDataAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string CallDataAmount { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class NetworkDto
+ public partial class PrepareTransactionRequest
{
- [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Name { get; set; }
-
- [Newtonsoft.Json.JsonProperty("chainId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string ChainId { get; set; }
-
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
- public NetworkType Type { get; set; }
-
- }
-
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public enum NetworkType
- {
-
- [System.Runtime.Serialization.EnumMember(Value = @"EVM")]
- EVM = 0,
-
- [System.Runtime.Serialization.EnumMember(Value = @"Solana")]
- Solana = 1,
-
- [System.Runtime.Serialization.EnumMember(Value = @"Starknet")]
- Starknet = 2,
-
- }
+ public TransactionType Type { get; set; }
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class NodeDto
- {
- [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string Url { get; set; }
+ [Newtonsoft.Json.JsonProperty("args", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Args { get; set; }
- [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
- public NodeType Type { get; set; }
+ [Newtonsoft.Json.JsonProperty("networkName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string NetworkName { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public enum NodeType
+ public partial class QuoteWithSolverDto
{
+ [Newtonsoft.Json.JsonProperty("totalFee", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string TotalFee { get; set; }
- [System.Runtime.Serialization.EnumMember(Value = @"Primary")]
- Primary = 0,
-
- [System.Runtime.Serialization.EnumMember(Value = @"DepositTracking")]
- DepositTracking = 1,
-
- [System.Runtime.Serialization.EnumMember(Value = @"Public")]
- Public = 2,
+ [Newtonsoft.Json.JsonProperty("totalServiceFee", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string TotalServiceFee { get; set; }
- [System.Runtime.Serialization.EnumMember(Value = @"Secondary")]
- Secondary = 3,
+ [Newtonsoft.Json.JsonProperty("totalExpenseFee", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string TotalExpenseFee { get; set; }
- }
+ [Newtonsoft.Json.JsonProperty("receiveAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ReceiveAmount { get; set; }
- [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
- public partial class QuoteDto
- {
- [Newtonsoft.Json.JsonProperty("totalFee", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double TotalFee { get; set; }
+ [Newtonsoft.Json.JsonProperty("sourceSolverAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string SourceSolverAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("totalFeeInUsd", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double TotalFeeInUsd { get; set; }
+ [Newtonsoft.Json.JsonProperty("destinationSolverAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string DestinationSolverAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("receiveAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double ReceiveAmount { get; set; }
+ [Newtonsoft.Json.JsonProperty("sourceContractAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string SourceContractAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("receiveAmountInUsd", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double ReceiveAmountInUsd { get; set; }
+ [Newtonsoft.Json.JsonProperty("destinationContractAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string DestinationContractAddress { get; set; }
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class RouteDto
{
- [Newtonsoft.Json.JsonProperty("source", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public TokenNetworkDto Source { get; set; }
+ [Newtonsoft.Json.JsonProperty("source", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public TokenNetworkDto Source { get; set; } = new TokenNetworkDto();
- [Newtonsoft.Json.JsonProperty("destionation", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public TokenNetworkDto Destionation { get; set; }
+ [Newtonsoft.Json.JsonProperty("destination", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public TokenNetworkDto Destination { get; set; } = new TokenNetworkDto();
}
@@ -1354,32 +887,35 @@ public partial class SwapDto
[Newtonsoft.Json.JsonProperty("commitId", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string CommitId { get; set; }
- [Newtonsoft.Json.JsonProperty("sourceNetwork", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string SourceNetwork { get; set; }
+ [Newtonsoft.Json.JsonProperty("hashlock", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Hashlock { get; set; }
- [Newtonsoft.Json.JsonProperty("sourceToken", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string SourceToken { get; set; }
+ [Newtonsoft.Json.JsonProperty("source", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public TokenNetworkDto Source { get; set; }
[Newtonsoft.Json.JsonProperty("sourceAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double SourceAmount { get; set; }
+ public string SourceAmount { get; set; }
[Newtonsoft.Json.JsonProperty("sourceAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string SourceAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("destinationNetwork", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string DestinationNetwork { get; set; }
+ [Newtonsoft.Json.JsonProperty("sourceContractAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string SourceContractAddress { get; set; }
- [Newtonsoft.Json.JsonProperty("destinationToken", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public string DestinationToken { get; set; }
+ [Newtonsoft.Json.JsonProperty("destination", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public TokenNetworkDto Destination { get; set; }
[Newtonsoft.Json.JsonProperty("destinationAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double DestinationAmount { get; set; }
+ public string DestinationAmount { get; set; }
[Newtonsoft.Json.JsonProperty("destinationAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string DestinationAddress { get; set; }
+ [Newtonsoft.Json.JsonProperty("destinationContractAddress", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string DestinationContractAddress { get; set; }
+
[Newtonsoft.Json.JsonProperty("feeAmount", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public double FeeAmount { get; set; }
+ public string FeeAmount { get; set; }
[Newtonsoft.Json.JsonProperty("transactions", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.Collections.Generic.ICollection Transactions { get; set; }
@@ -1398,9 +934,6 @@ public partial class TokenDto
[Newtonsoft.Json.JsonProperty("decimals", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public int Decimals { get; set; }
- [Newtonsoft.Json.JsonProperty("precision", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
- public int Precision { get; set; }
-
}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
diff --git a/TrainStation/Dockerfile b/TrainStation/Dockerfile
new file mode 100644
index 0000000..3392422
--- /dev/null
+++ b/TrainStation/Dockerfile
@@ -0,0 +1,19 @@
+ARG DOTNET_VERSION
+
+FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION}.0 AS base
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}.0 AS build
+WORKDIR /build
+
+COPY TrainStation/ TrainStation/
+
+FROM build AS publish
+RUN dotnet publish "TrainStation/API.csproj" -c Release -o /app/publish
+
+FROM base AS final
+
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Train.Station.API.dll"]
+EXPOSE 8080
\ No newline at end of file
diff --git a/TrainStation/Endpoints/StationEndpoints.cs b/TrainStation/Endpoints/StationEndpoints.cs
index a1ac488..6fad2a3 100644
--- a/TrainStation/Endpoints/StationEndpoints.cs
+++ b/TrainStation/Endpoints/StationEndpoints.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
+using System.Text;
using Train.Station.API.Models;
using Train.Station.API.Services;
using Train.Station.Client;
@@ -17,120 +18,113 @@ public static RouteGroupBuilder MapEndpoints(this RouteGroupBuilder group)
group.MapGet("/routes", GetAllRoutesAsync)
.Produces>();
- //group.MapGet("/quote", GetQuoteAsync)
- // .Produces();
+ group.MapGet("/quote", GetQuoteAsync)
+ .Produces();
- //group.MapGet("/{solver}/swaps", GetAllSwapsAsync)
- // .Produces();
+ group.MapGet("/{solver}/swaps/{commitId}", GetSwapAsync)
+ .Produces();
- //group.MapGet("/{solver}/swaps/{commitId}", GetSwapAsync)
- // .Produces();
-
- //group.MapPost("/{solver}/swaps/{commitId}/addLockSig", AddLockSigAsync)
- // .Produces();
+ group.MapPost("/{solver}/swaps/{commitId}/addLockSig", AddLockSigAsync)
+ .Produces();
return group;
}
+ private static async Task GetSwapAsync(
+ HttpContext httpContext,
+ SolverCache solverCache,
+ [FromRoute] string solver,
+ [FromRoute] string commitId,
+ IHttpClientFactory httpClientFactory)
+ {
+ if (!solverCache.GetAll().TryGetValue(solver, out var solverObj))
+ {
+ return Results.NotFound();
+ }
+
+ var httpClient = httpClientFactory.CreateClient(solver);
+ var trainSilverClient = new TrainSolverApiClient(
+ solverObj.Url.ToString(), httpClient);
- //private static async Task GetSwapRouteLimitsAsync(
- // HttpContext httpContext,
- // IRouteService routeService,
- // [AsParameters] GetRouteLimitsQueryParams queryParams)
- //{
- // var limit = await routeService.GetLimitAsync(
- // new()
- // {
- // SourceNetwork = queryParams.SourceNetwork!,
- // SourceToken = queryParams.SourceToken!,
- // DestinationNetwork = queryParams.DestinationNetwork!,
- // DestinationToken = queryParams.DestinationToken!,
- // });
-
- // if (limit == null)
- // {
- // return Results.NotFound(new ApiResponse()
- // {
- // Error = new ApiError()
- // {
- // Code = "LIMIT_NOT_FOUND",
- // Message = "Limit not found",
- // }
- // });
- // }
-
- // return Results.Ok(new ApiResponse { Data = limit });
- //}
+ var swap = await trainSilverClient.SwapsAsync(commitId);
- private static async Task GetNetworksAsync(
+ return Results.Ok(swap);
+ }
+
+ private static async Task AddLockSigAsync(
HttpContext httpContext,
- NetworkConfigurationCache networkConfigurationCache)
+ SolverCache solverCache,
+ [FromRoute] string solver,
+ [FromRoute] string commitId,
+ IHttpClientFactory httpClientFactory,
+ AddLockSignatureModel addLock)
{
- var networks = networkConfigurationCache.GetAll();
+ if (!solverCache.GetAll().TryGetValue(solver, out var solverObj))
+ {
+ return Results.NotFound();
+ }
+
+ var httpClient = httpClientFactory.CreateClient(solver);
+ var trainSilverClient = new TrainSolverApiClient(
+ solverObj.Url.ToString(), httpClient);
- return Results.Ok(networks);
+ var swap = await trainSilverClient.SwapsAsync(commitId);
+
+ if (swap == null)
+ {
+ return Results.NotFound();
+ }
+
+ var lockSig = await trainSilverClient.AddLockSigAsync(commitId, addLock);
+ return Results.Ok(lockSig);
}
- //private static async Task GetAllSourcesAsync(
- // IRouteService routeService,
- // INetworkRepository networkRepository,
- // [FromQuery] string? destinationNetwork,
- // [FromQuery] string? destinationToken)
- //{
- // var sources = await routeService.GetSourcesAsync(
- // networkName: destinationNetwork,
- // token: destinationToken);
-
- // if (sources == null || !sources.Any())
- // {
- // return Results.NotFound(new ApiResponse()
- // {
- // Error = new ApiError()
- // {
- // Code = "REACHABLE_POINTS_NOT_FOUND",
- // Message = "No reachable points found",
- // }
- // });
- // }
-
- // return Results.Ok(new ApiResponseListDetailedNetworkDto { Data = sources });
- //}
+ private static async Task GetNetworksAsync(
+ NetworkConfigurationCache networkConfigurationCache)
+ {
+ return Results.Ok(networkConfigurationCache.GetAll());
+ }
private static async Task GetAllRoutesAsync(
RouteCache routeCache)
{
- var routes = routeCache.GetAll();
+ var routes = await routeCache.GetAllAsync();
return Results.Ok(routes);
}
- //private static async Task GetQuoteAsync(
- // IRouteService routeService,
- // HttpContext httpContext,
- // [AsParameters] GetQuoteQueryParams queryParams)
- //{
- // var quoteRequest = new QuoteRequest
- // {
- // SourceNetwork = queryParams.SourceNetwork!,
- // SourceToken = queryParams.SourceToken!,
- // DestinationNetwork = queryParams.DestinationNetwork!,
- // DestinationToken = queryParams.DestinationToken!,
- // Amount = queryParams.Amount!.Value,
- // };
-
- // var quote = await routeService.GetValidatedQuoteAsync(quoteRequest);
-
- // if (quote == null)
- // {
- // return Results.NotFound(new ApiResponse()
- // {
- // Error = new ApiError()
- // {
- // Code = "QUOTE_NOT_FOUND",
- // Message = "Quote not found",
- // }
- // });
- // }
-
- // return Results.Ok(new ApiResponseQuoteDto { Data = quote });
- //}
+ private static async Task GetQuoteAsync(
+ RouteCache routeCache,
+ SolverCache solverCache,
+ IHttpClientFactory httpClientFactory,
+ [FromQuery] string sourceNetwork,
+ [FromQuery] string sourceToken,
+ [FromQuery] string destinationNetwork,
+ [FromQuery] string destinationToken,
+ [FromQuery] string amount)
+ {
+ var solvers = await routeCache.GetSolversByRouteAsync(
+ sourceNetwork,
+ sourceToken,
+ destinationNetwork,
+ destinationToken);
+
+ var solverName = solvers.First();
+
+ var solverInfo = solverCache.GetAll()[solverName];
+ var httpClient = httpClientFactory.CreateClient(solverName);
+
+ var trainSilverClient = new TrainSolverApiClient(
+ solverInfo.Url.ToString(), httpClient);
+
+ var quote = await trainSilverClient.QuoteAsync(
+ amount,
+ sourceNetwork,
+ sourceToken,
+ destinationNetwork,
+ destinationToken);
+
+ quote.Data.SolverName = solverName;
+
+ return Results.Ok(quote);
+ }
}
diff --git a/TrainStation/Models/NetworkConfiguration.cs b/TrainStation/Models/NetworkConfiguration.cs
index 05ecd77..41e1b9a 100644
--- a/TrainStation/Models/NetworkConfiguration.cs
+++ b/TrainStation/Models/NetworkConfiguration.cs
@@ -12,9 +12,11 @@ public class NetworkConfiguration
public string AccountExplorerTemplate { get; set; } = null!;
- public string NativeSymbol { get; set; } = null!;
+ public string NativeTokenSymbol { get; set; } = null!;
- public int Decimals { get; set; }
+ public int NativeTokenDecimals { get; set; }
public string RpcUrl { get; set; } = null!;
+
+ public string Type { get; set; } = null!;
}
diff --git a/TrainStation/Options/TrainStationOptions.cs b/TrainStation/Options/TrainStationOptions.cs
new file mode 100644
index 0000000..3e5a36e
--- /dev/null
+++ b/TrainStation/Options/TrainStationOptions.cs
@@ -0,0 +1,10 @@
+namespace Train.Station.API.Options;
+
+public class TrainStationOptions
+{
+ public const string SectionName = "TrainStation";
+
+ public string RedisConnectionString { get; set; } = null!;
+
+ public int RedisDatabaseIndex { get; set; } = 4;
+}
diff --git a/TrainStation/Program.cs b/TrainStation/Program.cs
index 18d1f63..bb44e10 100644
--- a/TrainStation/Program.cs
+++ b/TrainStation/Program.cs
@@ -1,7 +1,10 @@
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
using System.Text.Json.Serialization;
using System.Threading.RateLimiting;
using Train.Station.API.Endpoints;
using Train.Station.API.Extensions;
+using Train.Station.API.Options;
using Train.Station.API.Services;
var builder = WebApplication.CreateBuilder(args);
@@ -37,6 +40,17 @@
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
+var options = new TrainStationOptions();
+configuration.GetSection(TrainStationOptions.SectionName).Bind(options);
+
+builder.Services.AddSingleton(
+ ConnectionMultiplexer.Connect(options.RedisConnectionString));
+
+builder.Services.AddTransient(sp => sp
+ .GetRequiredService()
+ .GetDatabase(options.RedisDatabaseIndex));
+
+
builder.Services.AddHttpClient();
builder.Services.AddMemoryCache();
builder.Services.AddSingleton();
@@ -67,6 +81,9 @@
var app = builder.Build();
+app.UseRateLimiter();
+app.UseCors();
+
app.MapGroup("/api")
.MapGet("/health", () => Results.Ok())
.WithTags("System")
@@ -85,7 +102,5 @@
c.DisplayRequestDuration();
});
-app.UseRateLimiter();
-app.UseCors();
await app.RunAsync();
diff --git a/TrainStation/Services/JsonFileCache.cs b/TrainStation/Services/JsonFileCache.cs
new file mode 100644
index 0000000..df8ec80
--- /dev/null
+++ b/TrainStation/Services/JsonFileCache.cs
@@ -0,0 +1,28 @@
+using System.Text.Json;
+
+namespace Train.Station.API.Services;
+
+public abstract class JsonFileCache
+{
+ protected TCollection Items { get; }
+
+ protected JsonFileCache(
+ IWebHostEnvironment env,
+ string fileName,
+ Func, TCollection> transform)
+ {
+ var filePath = Path.Combine(env.ContentRootPath, fileName);
+ if (!File.Exists(filePath))
+ {
+ throw new FileNotFoundException($"Could not find {fileName}", filePath);
+ }
+
+ var json = File.ReadAllText(filePath);
+ var deserialized = JsonSerializer.Deserialize>(json, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ }) ?? throw new InvalidOperationException($"Deserialization of {fileName} returned null.");
+
+ Items = transform(deserialized);
+ }
+}
\ No newline at end of file
diff --git a/TrainStation/Services/NetworkConfigurationCache.cs b/TrainStation/Services/NetworkConfigurationCache.cs
index 5102b1c..d1a84c0 100644
--- a/TrainStation/Services/NetworkConfigurationCache.cs
+++ b/TrainStation/Services/NetworkConfigurationCache.cs
@@ -3,24 +3,10 @@
namespace Train.Station.API.Services;
-public class NetworkConfigurationCache
+public class NetworkConfigurationCache(
+ IWebHostEnvironment env)
+ : JsonFileCache, NetworkConfiguration>(
+ env, "networks.json", list => list)
{
- private readonly List _networks;
-
- public NetworkConfigurationCache(IWebHostEnvironment env)
- {
- var filePath = Path.Combine(env.ContentRootPath, "networks.json");
- if (!File.Exists(filePath))
- {
- throw new FileNotFoundException("Could not find networks.json", filePath);
- }
-
- var json = File.ReadAllText(filePath);
- _networks = JsonSerializer.Deserialize>(json, new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true
- }) ?? new List();
- }
-
- public IReadOnlyList GetAll() => _networks;
+ public IReadOnlyList GetAll() => Items;
}
\ No newline at end of file
diff --git a/TrainStation/Services/RouteCache.cs b/TrainStation/Services/RouteCache.cs
index 26876de..fc8ec3f 100644
--- a/TrainStation/Services/RouteCache.cs
+++ b/TrainStation/Services/RouteCache.cs
@@ -1,132 +1,88 @@
-using Microsoft.Extensions.Caching.Memory;
-using System.Collections.Concurrent;
+using Microsoft.AspNetCore.DataProtection.KeyManagement;
+using Microsoft.AspNetCore.Routing;
+using StackExchange.Redis;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using Train.Station.Client;
namespace Train.Station.API.Services;
-public class RouteCache(IMemoryCache cache, NetworkConfigurationCache networkConfigCache)
+public class RouteCache(
+ IDatabase cache,
+ IConnectionMultiplexer connectionMultiplexer,
+ NetworkConfigurationCache networkConfigCache)
{
- private readonly ConcurrentDictionary> _routeToLps = new();
private readonly HashSet _validNetworkNames = networkConfigCache
.GetAll()
.Select(n => n.Name)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
- public void AddOrUpdateRoute(string lpId, IEnumerable routes, TimeSpan ttl)
+ public async Task AddOrUpdateRouteAsync(string lpId, IEnumerable routes, TimeSpan ttl)
{
foreach (var route in routes)
{
if (!_validNetworkNames.Contains(route.Source.Network.Name) ||
- !_validNetworkNames.Contains(route.Destionation.Network.Name))
+ !_validNetworkNames.Contains(route.Destination.Network.Name))
{
continue;
}
- string key = GetRouteKey(route);
+ await cache.SortedSetAddAsync(
+ "ROUTES",
+ JsonSerializer.Serialize(route),
+ DateTimeOffset.UtcNow.ToUnixTimeSeconds());
- var cacheEntryOptions = new MemoryCacheEntryOptions
- {
- AbsoluteExpirationRelativeToNow = ttl,
- PostEvictionCallbacks =
- {
- new PostEvictionCallbackRegistration
- {
- EvictionCallback = (evictedKey, value, reason, state) =>
- {
- var routeKey = (string)evictedKey;
-
- if (_routeToLps.TryGetValue(routeKey, out var lpSet))
- {
- lpSet.TryRemove(lpId, out _);
-
- if (lpSet.IsEmpty)
- _routeToLps.TryRemove(routeKey, out _);
- }
- }
- }
- }
- };
-
- cache.Set(key, route, cacheEntryOptions);
-
- if (_routeToLps.TryGetValue(key, out var lpMap))
- {
- lpMap[lpId] = true;
- }
- else
- {
- _routeToLps[key] = new ConcurrentDictionary(
- [new KeyValuePair(lpId, true)]);
- }
+ await cache.SetAddAsync(
+ GetRouteKey("SOLVERS", route),
+ new RedisValue(lpId));
}
}
- public HashSet GetAll()
+ public async Task> GetAllAsync()
{
- var routes = new HashSet();
+ var now = DateTimeOffset.UtcNow;
+ var start = now.AddMinutes(-5).ToUnixTimeSeconds();
+ var end = now.ToUnixTimeSeconds();
- foreach (var key in _routeToLps.Keys)
- {
- if (cache.TryGetValue(key, out var route))
- {
- routes.Add(route);
- }
- }
+ var members = await cache.SortedSetRangeByScoreAsync("ROUTES", start, end);
- return routes;
- }
+ var entries = new List();
- public HashSet GetAllSources()
- {
- var sources = new HashSet();
- foreach (var key in _routeToLps.Keys)
+ foreach (var member in members)
{
- if (cache.TryGetValue(key, out var route))
+ try
{
- sources.Add(route.Source);
+ var dto = JsonSerializer.Deserialize(member);
+ if (dto != null)
+ entries.Add(dto);
}
- }
- return sources;
- }
-
- public HashSet GetAllDestinations()
- {
- var destinations = new HashSet();
- foreach (var key in _routeToLps.Keys)
- {
- if (cache.TryGetValue(key, out var route))
+ catch
{
- destinations.Add(route.Destionation);
}
}
- return destinations;
+ return entries;
}
- public IEnumerable GetLpsByRoute(string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken)
+ public async Task> GetSolversByRouteAsync(string sourceNetwork, string sourceToken, string destinationNetwork, string destinationToken)
{
- var requestedRouteKey = GetRouteKey(sourceNetwork, sourceToken, destinationNetwork, destinationToken);
-
- if (_routeToLps.TryGetValue(requestedRouteKey, out var lps))
- {
- return lps.Keys;
- }
-
- return Enumerable.Empty();
+ var members = await cache.SetMembersAsync(GetRouteKey("SOLVERS", sourceNetwork, sourceToken, destinationNetwork, destinationToken));
+ return members.Select(m => m.ToString());
}
- private static string GetRouteKey(string sourceNetwork, string sourceToken, string destNetwork, string destToken)
+ private static string GetRouteKey(string prefix, string sourceNetwork, string sourceToken, string destNetwork, string destToken)
{
- return $"{sourceNetwork}.{sourceToken}->{destNetwork}.{destToken}";
+ return $"{prefix}:{sourceNetwork}.{sourceToken}->{destNetwork}.{destToken}";
}
- private static string GetRouteKey(RouteDto r)
+ private static string GetRouteKey(string prefix, RouteDto r)
{
return GetRouteKey(
+ prefix,
r.Source.Network.Name,
r.Source.Token.Symbol,
- r.Destionation.Network.Name,
- r.Destionation.Token.Symbol
+ r.Destination.Network.Name,
+ r.Destination.Token.Symbol
);
}
}
diff --git a/TrainStation/Services/RoutePollingService.cs b/TrainStation/Services/RoutePollingService.cs
index fe06bee..2421f12 100644
--- a/TrainStation/Services/RoutePollingService.cs
+++ b/TrainStation/Services/RoutePollingService.cs
@@ -15,8 +15,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
- var name = lp.Name;
- var baseAddress = lp.Url.ToString();
+ var name = lp.Key;
+ var baseAddress = lp.Value.Url.ToString();
var trainSilverClient = new TrainSolverApiClient(
baseAddress,
@@ -29,7 +29,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
continue;
}
- routeCache.AddOrUpdateRoute(name, routesResponse.Data, TimeSpan.FromMinutes(10));
+ await routeCache.AddOrUpdateRouteAsync(name, routesResponse.Data, TimeSpan.FromMinutes(5));
}
catch (Exception ex)
{
diff --git a/TrainStation/Services/SolverCache.cs b/TrainStation/Services/SolverCache.cs
index e01e0be..bf69caf 100644
--- a/TrainStation/Services/SolverCache.cs
+++ b/TrainStation/Services/SolverCache.cs
@@ -1,26 +1,12 @@
-using System.Text.Json;
+using System.Collections.Concurrent;
+using System.Text.Json;
using Train.Station.API.Models;
namespace Train.Station.API.Services;
-public class SolverCache
+public class SolverCache(IWebHostEnvironment env)
+ : JsonFileCache, Solver>(
+ env, "solvers.json", list => list.ToDictionary(x => x.Name))
{
- private readonly List _solvers;
-
- public SolverCache(IWebHostEnvironment env)
- {
- var filePath = Path.Combine(env.ContentRootPath, "solvers.json");
- if (!File.Exists(filePath))
- {
- throw new FileNotFoundException("Could not find lp.json", filePath);
- }
-
- var json = File.ReadAllText(filePath);
- _solvers = JsonSerializer.Deserialize>(json, new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true
- }) ?? new List();
- }
-
- public IReadOnlyList GetAll() => _solvers;
+ public IReadOnlyDictionary GetAll() => Items;
}
\ No newline at end of file
diff --git a/TrainStation/networks.json b/TrainStation/networks.json
index ca6c277..423473d 100644
--- a/TrainStation/networks.json
+++ b/TrainStation/networks.json
@@ -5,9 +5,10 @@
"ChainId": "11155111",
"TransactionExplorerTemplate": "https://sepolia.etherscan.io/tx/{0}",
"AccountExplorerTemplate": "https://sepolia.etherscan.io/address/{0}",
- "NativeSymbol": "ETH",
- "Decimals": 18,
- "RpcUrl": "https://ethereum-sepolia-rpc.publicnode.com"
+ "NativeTokenSymbol": "ETH",
+ "NativeTokenDecimals": 18,
+ "RpcUrl": "https://ethereum-sepolia-rpc.publicnode.com",
+ "Type": "EVM"
},
{
"Name": "ARBITRUM_SEPOLIA",
@@ -15,9 +16,10 @@
"ChainId": "421614",
"TransactionExplorerTemplate": "https://sepolia.arbiscan.io/tx/{0}",
"AccountExplorerTemplate": "https://sepolia.arbiscan.io/address/{0}",
- "NativeSymbol": "ETH",
- "Decimals": 18,
- "RpcUrl": "https://arbitrum-sepolia-rpc.publicnode.com"
+ "NativeTokenSymbol": "ETH",
+ "NativeTokenDecimals": 18,
+ "RpcUrl": "https://arbitrum-sepolia-rpc.publicnode.com",
+ "Type": "EVM"
},
{
"Name": "OPTIMISM_SEPOLIA",
@@ -25,9 +27,10 @@
"ChainId": "11155420",
"TransactionExplorerTemplate": "https://sepolia-optimism.etherscan.io/tx/{0}",
"AccountExplorerTemplate": "https://sepolia-optimism.etherscan.io/address/{0}",
- "NativeSymbol": "ETH",
- "Decimals": 18,
- "RpcUrl": "https://sepolia.optimism.io"
+ "NativeTokenSymbol": "ETH",
+ "NativeTokenDecimals": 18,
+ "RpcUrl": "https://sepolia.optimism.io",
+ "Type": "EVM"
},
{
"Name": "STARKNET_SEPOLIA",
@@ -35,9 +38,10 @@
"ChainId": "0x534e5f5345504f4c4941",
"TransactionExplorerTemplate": "https://sepolia.starkscan.co/tx/{0}",
"AccountExplorerTemplate": "https://sepolia.starkscan.co/contract/{0}",
- "NativeSymbol": "ETH",
- "Decimals": 18,
- "RpcUrl": "https://starknet-sepolia.public.blastapi.io"
+ "NativeTokenSymbol": "ETH",
+ "NativeTokenDecimals": 18,
+ "RpcUrl": "https://starknet-sepolia.public.blastapi.io",
+ "Type": "EVM"
},
{
"Name": "SOLANA_DEVNET",
@@ -45,8 +49,20 @@
"ChainId": "devnet",
"TransactionExplorerTemplate": "https://explorer.solana.com/tx/{0}?cluster=devnet",
"AccountExplorerTemplate": "https://explorer.solana.com/address/{0}?cluster=devnet",
- "NativeSymbol": "SOL",
- "Decimals": 9,
- "RpcUrl": "https://api.devnet.solana.com"
+ "NativeTokenSymbol": "SOL",
+ "NativeTokenDecimals": 9,
+ "RpcUrl": "https://api.devnet.solana.com",
+ "Type": "Solana"
+ },
+ {
+ "Name": "FUEL_TESTNET",
+ "DisplayName": "Fuel Testnet",
+ "ChainId": "0",
+ "TransactionExplorerTemplate": "https://app-testnet.fuel.network/tx/{0}",
+ "AccountExplorerTemplate": "https://app-testnet.fuel.network/account/{0}/assets",
+ "NativeTokenSymbol": "ETH",
+ "NativeTokenDecimals": 9,
+ "RpcUrl": "https://testnet.fuel.network/v1/graphql",
+ "Type": "Fuel"
}
-]
\ No newline at end of file
+]
diff --git a/TrainStation/solvers.json b/TrainStation/solvers.json
index 9ffebca..028d9be 100644
--- a/TrainStation/solvers.json
+++ b/TrainStation/solvers.json
@@ -2,6 +2,6 @@
{
"name": "EC69",
"url": "https://train.dev.lb.layerswap.cloud",
- "version" : "v1"
+ "version": "v1"
}
]
\ No newline at end of file