diff --git a/.ckb-version b/.ckb-version index 5ee8d4a..787ffc3 100644 --- a/.ckb-version +++ b/.ckb-version @@ -1 +1 @@ -0.42.0-rc1 +0.42.0 diff --git a/README.md b/README.md index 8811387..fe69f73 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,35 @@ brew install nervosnetwork/tap/tippy ### Tippy Console and UI -While Tippy runs as a console application, it also provides web UI. By default the dashboard UI will be opened automatically, if not you can access it by visiting [http://localhost:5000/Home](http://localhost:5000/Home) from a browser. +While Tippy runs as a console application, it also provides web UI. By default the dashboard UI will be opened automatically, if not you can access it by visiting [http://localhost:5000/](http://localhost:5000/) from a browser. + +### Override the App URL + +If you want to access the Web UI and Tippy API from another URL than the default `http://localhost` URL, there are two options. + +#### 1. Set Environment Variable `ASPNETCORE_URLS` + +On Linux you can set the `ASPNETCORE_URLS` Environment Variable to override the default App URL. For example, launch Tippy this way to use `http://0.0.0.0:5000`: + +```shell +ASPNETCORE_URLS="http://0.0.0.0:5000" tippy +``` + +#### 2. Modify `appsettings.json` + +You can also modify `appsettings.json` file to override the default App URL. For example, add the following section to use `http://0.0.0.0:5000`: + +```json +"Kestrel": { + "EndPoints": { + "Http": { + "Url": "http://0.0.0.0:5000" + } + } +} +``` + +`appsettings.json` locates in `/Applications/Tippy.app/Contents/MacOS/` on macOS and in the root Tippy folder on Windows/Linux. If Tippy is installed with Homebrew on Linux then it locates in `/home/linuxbrew/.linuxbrew/Cellar/tippy-linux/[version]/libexec/`. ### Debugger @@ -100,6 +128,10 @@ http://localhost:5000/api See [CKB JSON-RPC doc](https://docs.nervos.org/docs/reference/rpc) for more information. +### The `send_transaction` API method + +If you call CKB's `send_transaction` API method through Tippy API, the transactions will be recorded in Tippy. Go to the `Recorded Transactions` tab to view them. + ### Tippy RPCs #### Method `create_chain` @@ -462,7 +494,7 @@ Response ``` 4. Open `Tippy.sln` with Visual Studio 2019 (v16.8 or later), Visual Studio 2019 for Mac (v8.8 or later), or Visual Studio Code 5. Select `Tippy` as startup project for the solution, then start debugging it -6. Browse `http://localhost:5000/home` in your browser +6. Browse `http://localhost:5000/` in your browser ### Add Database Migration diff --git a/src/Tippy.Core/Data/TippyDbContext.cs b/src/Tippy.Core/Data/TippyDbContext.cs index 4462289..9ac3597 100644 --- a/src/Tippy.Core/Data/TippyDbContext.cs +++ b/src/Tippy.Core/Data/TippyDbContext.cs @@ -12,7 +12,7 @@ public TippyDbContext(DbContextOptions options) public DbSet Projects { get; set; } = null!; public DbSet Tokens { get; set; } = null!; - public DbSet FailedTransactions { get; set; } = null!; + public DbSet RecordedTransactions { get; set; } = null!; public DbSet DeniedTransactions { get; set; } = null!; protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -30,9 +30,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .WithMany(p => p.Tokens) .OnDelete(DeleteBehavior.Cascade); - modelBuilder.Entity() + modelBuilder.Entity() .HasOne(t => t.Project) - .WithMany(p => p.FailedTransactions) + .WithMany(p => p.RecordedTransactions) .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() diff --git a/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.Designer.cs b/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.Designer.cs new file mode 100644 index 0000000..17426cc --- /dev/null +++ b/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.Designer.cs @@ -0,0 +1,202 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Tippy.Core.Data; + +namespace Tippy.Core.Migrations +{ + [DbContext(typeof(TippyDbContext))] + [Migration("20210526233521_RenameFailedTransactionsToRecordedTransactions")] + partial class RenameFailedTransactionsToRecordedTransactions + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.0"); + + modelBuilder.Entity("Tippy.Core.Models.DeniedTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DenyType") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("TxHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TxHash", "DenyType") + .IsUnique(); + + b.ToTable("DeniedTransactions"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Chain") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExtraToml") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IndexerRpcPort") + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("LockArg") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("NodeNetworkPort") + .HasColumnType("INTEGER"); + + b.Property("NodeRpcPort") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Error") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("RawTransaction") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("RecordedTransactions"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Token", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Decimals") + .HasColumnType("INTEGER"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("Symbol") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptArgs") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptCodeHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptHashType") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Tippy.Core.Models.DeniedTransaction", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("DeniedTransactions") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("RecordedTransactions") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Token", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("Tokens") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Project", b => + { + b.Navigation("DeniedTransactions"); + + b.Navigation("RecordedTransactions"); + + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.cs b/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.cs new file mode 100644 index 0000000..313e76a --- /dev/null +++ b/src/Tippy.Core/Migrations/20210526233521_RenameFailedTransactionsToRecordedTransactions.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tippy.Core.Migrations +{ + public partial class RenameFailedTransactionsToRecordedTransactions : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FailedTransactions"); + + migrationBuilder.CreateTable( + name: "RecordedTransactions", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RawTransaction = table.Column(type: "TEXT", nullable: false), + Error = table.Column(type: "TEXT", nullable: false), + CreatedAt = table.Column(type: "TEXT", nullable: false), + ProjectId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RecordedTransactions", x => x.Id); + table.ForeignKey( + name: "FK_RecordedTransactions_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_RecordedTransactions_ProjectId", + table: "RecordedTransactions", + column: "ProjectId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RecordedTransactions"); + + migrationBuilder.CreateTable( + name: "FailedTransactions", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false), + Error = table.Column(type: "TEXT", nullable: false), + ProjectId = table.Column(type: "INTEGER", nullable: false), + RawTransaction = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FailedTransactions", x => x.Id); + table.ForeignKey( + name: "FK_FailedTransactions_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_FailedTransactions_ProjectId", + table: "FailedTransactions", + column: "ProjectId"); + } + } +} diff --git a/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.Designer.cs b/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.Designer.cs new file mode 100644 index 0000000..ead6595 --- /dev/null +++ b/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.Designer.cs @@ -0,0 +1,206 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Tippy.Core.Data; + +namespace Tippy.Core.Migrations +{ + [DbContext(typeof(TippyDbContext))] + [Migration("20210526235625_AddTxHashToRecordedTransaction")] + partial class AddTxHashToRecordedTransaction + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.0"); + + modelBuilder.Entity("Tippy.Core.Models.DeniedTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DenyType") + .HasColumnType("INTEGER"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("TxHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TxHash", "DenyType") + .IsUnique(); + + b.ToTable("DeniedTransactions"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Chain") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ExtraToml") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IndexerRpcPort") + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("LockArg") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("NodeNetworkPort") + .HasColumnType("INTEGER"); + + b.Property("NodeRpcPort") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Error") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("RawTransaction") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TxHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("RecordedTransactions"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Token", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Decimals") + .HasColumnType("INTEGER"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("Symbol") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptArgs") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptCodeHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TypeScriptHashType") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Tippy.Core.Models.DeniedTransaction", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("DeniedTransactions") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("RecordedTransactions") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Token", b => + { + b.HasOne("Tippy.Core.Models.Project", "Project") + .WithMany("Tokens") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + }); + + modelBuilder.Entity("Tippy.Core.Models.Project", b => + { + b.Navigation("DeniedTransactions"); + + b.Navigation("RecordedTransactions"); + + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.cs b/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.cs new file mode 100644 index 0000000..72e3049 --- /dev/null +++ b/src/Tippy.Core/Migrations/20210526235625_AddTxHashToRecordedTransaction.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tippy.Core.Migrations +{ + public partial class AddTxHashToRecordedTransaction : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TxHash", + table: "RecordedTransactions", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TxHash", + table: "RecordedTransactions"); + } + } +} diff --git a/src/Tippy.Core/Migrations/TippyDbContextModelSnapshot.cs b/src/Tippy.Core/Migrations/TippyDbContextModelSnapshot.cs index 303bf4e..6dad37a 100644 --- a/src/Tippy.Core/Migrations/TippyDbContextModelSnapshot.cs +++ b/src/Tippy.Core/Migrations/TippyDbContextModelSnapshot.cs @@ -42,33 +42,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("DeniedTransactions"); }); - modelBuilder.Entity("Tippy.Core.Models.FailedTransaction", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Error") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("ProjectId") - .HasColumnType("INTEGER"); - - b.Property("RawTransaction") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("ProjectId"); - - b.ToTable("FailedTransactions"); - }); - modelBuilder.Entity("Tippy.Core.Models.Project", b => { b.Property("Id") @@ -110,6 +83,37 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Projects"); }); + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Error") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProjectId") + .HasColumnType("INTEGER"); + + b.Property("RawTransaction") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TxHash") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("RecordedTransactions"); + }); + modelBuilder.Entity("Tippy.Core.Models.Token", b => { b.Property("Id") @@ -164,10 +168,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Project"); }); - modelBuilder.Entity("Tippy.Core.Models.FailedTransaction", b => + modelBuilder.Entity("Tippy.Core.Models.RecordedTransaction", b => { b.HasOne("Tippy.Core.Models.Project", "Project") - .WithMany("FailedTransactions") + .WithMany("RecordedTransactions") .HasForeignKey("ProjectId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -190,7 +194,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Navigation("DeniedTransactions"); - b.Navigation("FailedTransactions"); + b.Navigation("RecordedTransactions"); b.Navigation("Tokens"); }); diff --git a/src/Tippy.Core/Models/Project.cs b/src/Tippy.Core/Models/Project.cs index 24f6cfb..5a16af7 100644 --- a/src/Tippy.Core/Models/Project.cs +++ b/src/Tippy.Core/Models/Project.cs @@ -46,7 +46,7 @@ public enum ChainType public string ExtraToml { get; set; } = ""; public List Tokens { get; set; } = default!; - public List FailedTransactions { get; set; } = default!; + public List RecordedTransactions { get; set; } = default!; public List DeniedTransactions { get; set; } = default!; } } diff --git a/src/Tippy.Core/Models/FailedTransaction.cs b/src/Tippy.Core/Models/RecordedTransaction.cs similarity index 80% rename from src/Tippy.Core/Models/FailedTransaction.cs rename to src/Tippy.Core/Models/RecordedTransaction.cs index e63086c..f1576f2 100644 --- a/src/Tippy.Core/Models/FailedTransaction.cs +++ b/src/Tippy.Core/Models/RecordedTransaction.cs @@ -2,9 +2,10 @@ namespace Tippy.Core.Models { - public class FailedTransaction + public class RecordedTransaction { public int Id { get; set; } + public string TxHash { get; set; } = ""; public string RawTransaction { get; set; } = ""; diff --git a/src/Tippy.Core/Settings.cs b/src/Tippy.Core/Settings.cs index c0eb3d7..78e8a23 100644 --- a/src/Tippy.Core/Settings.cs +++ b/src/Tippy.Core/Settings.cs @@ -8,6 +8,7 @@ namespace Tippy.Core public class Settings { public AppSettings AppSettings { get; set; } = default!; + public string AppUrl { get; set; } = ""; private static Settings? singleton; public static Settings GetSettings() diff --git a/src/Tippy.Ctrl/Process/BinariesInfo.cs b/src/Tippy.Ctrl/Process/BinariesInfo.cs index a77e1f7..4189a4f 100644 --- a/src/Tippy.Ctrl/Process/BinariesInfo.cs +++ b/src/Tippy.Ctrl/Process/BinariesInfo.cs @@ -57,8 +57,17 @@ void RefreshDebuggerDeps() process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = dep; process.StartInfo.Arguments = "--version"; - process.StartInfo.WorkingDirectory = Core.Environment.GetAppDataFolder(); - process.Start(); + process.StartInfo.WorkingDirectory = Core.Environment.GetAppDataFolder(); + process.StartInfo.RedirectStandardOutput = true; + process.OutputDataReceived += (sender, e) => + { + if (!String.IsNullOrEmpty(e.Data)) + { + Info += e.Data + "\n"; + } + }; + process.Start(); + process.BeginOutputReadLine(); process.WaitForExit(); } catch diff --git a/src/Tippy/Api/TippyRpc.cs b/src/Tippy/Api/TippyRpc.cs index 9e67a74..1792c94 100644 --- a/src/Tippy/Api/TippyRpc.cs +++ b/src/Tippy/Api/TippyRpc.cs @@ -557,6 +557,12 @@ class ErrorResponseObject public Error Error { get; set; } = default!; } + class ResultResponseObject + { + [JsonPropertyName("result")] + public object Result { get; set; } = default!; + } + class RawRpcClient { readonly string Url; @@ -600,22 +606,25 @@ class TransactionRecorder internal static async void RecordIfNecessary(TippyDbContext dbContext, RequestObject request, string result, Project project) { var error = JsonSerializer.Deserialize(result); - if (error != null) + var txHash = JsonSerializer.Deserialize(result); + var shouldRecord = true; // error != null; + if (shouldRecord) { object raw = ""; if (request.Params != null && request.Params.Length > 0) { raw = request.Params[0]; } - var tx = new FailedTransaction + var tx = new RecordedTransaction { ProjectId = project.Id, + TxHash = txHash?.Result?.ToString() ?? "", RawTransaction = JsonSerializer.Serialize(raw), - Error = error.Error.Message, + Error = error?.Error?.Message ?? "", CreatedAt = DateTime.Now }; - dbContext.FailedTransactions.Add(tx); + dbContext.RecordedTransactions.Add(tx); await dbContext.SaveChangesAsync(); } } diff --git a/src/Tippy/Pages/Config/Index.cshtml b/src/Tippy/Pages/Config/Index.cshtml index 191f499..c43d288 100644 --- a/src/Tippy/Pages/Config/Index.cshtml +++ b/src/Tippy/Pages/Config/Index.cshtml @@ -27,6 +27,12 @@ +
+
+

App Url: @Model.AppUrl

+
+
+