Skip to content

Commit

Permalink
Implemente OpenSea importer
Browse files Browse the repository at this point in the history
  • Loading branch information
dlipicar committed Mar 28, 2024
1 parent 7cad03e commit 800cfb3
Show file tree
Hide file tree
Showing 26 changed files with 681 additions and 10 deletions.
2 changes: 2 additions & 0 deletions NftFaucet.Domain/Models/Abstraction/IToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ public interface IToken
public DateTime CreatedAt { get; }
public ITokenMedia MainFile { get; }
public ITokenMedia CoverFile { get; }
public Guid? ImporterId { get; set; }
public string Location { get; }
}
2 changes: 2 additions & 0 deletions NftFaucet.Domain/Models/Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public class Token : IToken
public DateTime CreatedAt { get; set; } = DateTime.Now;
public ITokenMedia MainFile { get; set; }
public ITokenMedia CoverFile { get; set; }
public Guid? ImporterId { get; set; }
public string Location { get; set; } = "";
}
8 changes: 8 additions & 0 deletions NftFaucet.Domain/Services/ITokenMediaDownloader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using NftFaucet.Domain.Models.Abstraction;

namespace NftFaucet.Domain.Services;

public interface ITokenMediaDownloader
{
public Task<ITokenMedia> Download(Uri location);
}
30 changes: 30 additions & 0 deletions NftFaucet.Domain/Services/TokenMediaDownloader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Net.Http;
using NftFaucet.Domain.Models;
using NftFaucet.Domain.Models.Abstraction;

namespace NftFaucet.Domain.Services;

public class TokenMediaDownloader : ITokenMediaDownloader
{
public async Task<ITokenMedia> Download(Uri location)
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(location);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"TokenMediaDownloader Status: {(int) response.StatusCode}. Reason: {response.ReasonPhrase}");
}

var fileData = await response.Content.ReadAsByteArrayAsync();
var fileName = location.Segments[^1];
var fileType = response.Content.Headers.ContentType.MediaType;
var fileSize = fileData.Length;
return new TokenMedia
{
FileName = fileName,
FileType = fileType,
FileData = $"data:{fileType};base64,{Convert.ToBase64String(fileData)}",
FileSize = fileSize,
};
}
}
7 changes: 7 additions & 0 deletions NftFaucet.Infrastructure/Models/Dto/ImporterStateDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace NftFaucet.Infrastructure.Models.Dto;

public class ImporterStateDto
{
public Guid Id { get; set; }
public string State { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public class PluginStateStorage
public ICollection<IWallet> Wallets { get; set; }
public ICollection<IUploader> Uploaders { get; set; }
public ICollection<IContract> Contracts { get; set; }
public ICollection<IImporter> Importers { get; set; }
}
2 changes: 2 additions & 0 deletions NftFaucet.Infrastructure/Repositories/IStateRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ public interface IStateRepository
public Task SaveUploadLocation(ITokenUploadLocation uploadLocation);
public Task SaveWalletState(IWallet wallet);
public Task SaveUploaderState(IUploader uploader);
public Task SaveImporterState(IImporter importer);

public Task LoadAppState(ScopedAppState appState);
public Task<IToken[]> LoadTokens();
public Task<ITokenUploadLocation[]> LoadUploadLocations();
public Task<UploaderStateDto[]> LoadUploaderStates();
public Task<WalletStateDto[]> LoadWalletStates();
public Task<ImporterStateDto[]> LoadImporterStates();

public Task DeleteTokenLocation(Guid uploadLocationId);
public Task DeleteToken(Guid tokenId);
Expand Down
35 changes: 35 additions & 0 deletions NftFaucet.Infrastructure/Repositories/StateRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class StateRepository : IStateRepository
private const string UploadLocationsStoreName = "UploadLocations";
private const string WalletStatesStoreName = "WalletStates";
private const string UploaderStatesStoreName = "UploaderStates";
private const string ImporterStatesStoreName = "ImporterStates";

public StateRepository(IndexedDBManager dbManager, Mapper mapper)
{
Expand Down Expand Up @@ -167,6 +168,40 @@ public async Task SaveUploaderState(IUploader uploader)
}
}

public async Task<ImporterStateDto[]> LoadImporterStates()
{
var existingImporterStates = await _dbManager.GetRecords<ImporterStateDto>(ImporterStatesStoreName);
if (existingImporterStates == null || existingImporterStates.Count == 0)
return Array.Empty<ImporterStateDto>();

return existingImporterStates.ToArray();
}

public async Task SaveImporterState(IImporter importer)
{
var state = await importer.GetState();
var stateDto = new ImporterStateDto
{
Id = importer.Id,
State = state,
};
var record = new StoreRecord<ImporterStateDto>
{
Storename = ImporterStatesStoreName,
Data = stateDto,
};

var existingStateDto = await _dbManager.GetRecordById<Guid, ImporterStateDto>(ImporterStatesStoreName, stateDto.Id);
if (existingStateDto == null)
{
await _dbManager.AddRecord(record);
}
else
{
await _dbManager.UpdateRecord(record);
}
}

public async Task<WalletStateDto[]> LoadWalletStates()
{
var existingWalletStates = await _dbManager.GetRecords<WalletStateDto>(WalletStatesStoreName);
Expand Down
8 changes: 8 additions & 0 deletions NftFaucet.Plugins/IImporterPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using NftFaucet.Plugins.Models.Abstraction;

namespace NftFaucet.Plugins;

public interface IImporterPlugin
{
public IReadOnlyCollection<IImporter> Importers { get; }
}
10 changes: 10 additions & 0 deletions NftFaucet.Plugins/Models/Abstraction/IImporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Numerics;
using NftFaucet.Domain.Models.Abstraction;

namespace NftFaucet.Plugins.Models.Abstraction;

public interface IImporter : INamedEntity, IEntityWithOrder, IStateful, IInitializable, IEntityWithProperties, IConfigurable
{
public Task<IToken> Import(ulong chainId, string contractAddress, BigInteger tokenId);
public bool IsChainIDSupported(ulong chainId);
}
11 changes: 11 additions & 0 deletions NftFaucet.Plugins/Models/Importer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Numerics;
using NftFaucet.Domain.Models.Abstraction;
using NftFaucet.Plugins.Models.Abstraction;

namespace NftFaucet.Plugins.Models;

public abstract class Importer : DefaultEntity, IImporter
{
public abstract Task<IToken> Import(ulong chainId, string contractAddress, BigInteger tokenId);
public abstract bool IsChainIDSupported(ulong chainId);
}
16 changes: 16 additions & 0 deletions NftFaucet.sln
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
#
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion =
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NftFaucet", "NftFaucet\NftFaucet.csproj", "{E113DAEE-A1E4-4BE2-8CDA-6E06245A471A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NftFaucet.Plugins", "NftFaucet.Plugins\NftFaucet.Plugins.csproj", "{CF83F0DB-41CD-46AA-8696-8351E098986D}"
Expand Down Expand Up @@ -44,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NftFaucet.NetworkPlugins.So
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NftFaucet.Infrastructure", "NftFaucet.Infrastructure\NftFaucet.Infrastructure.csproj", "{06949AF1-D775-4E6B-A309-C358B05F4D50}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ImportPlugins", "ImportPlugins", "{BE7D3C27-91BF-4EC0-A9C8-462B3FC6C9EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NftFaucet.ImportPlugins.OpenSea", "plugins\import-plugins\NftFaucet.ImportPlugins.OpenSea\NftFaucet.ImportPlugins.OpenSea.csproj", "{BC5740C3-D439-413C-8CA0-4D0EED720513}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -122,6 +129,13 @@ Global
{06949AF1-D775-4E6B-A309-C358B05F4D50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06949AF1-D775-4E6B-A309-C358B05F4D50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06949AF1-D775-4E6B-A309-C358B05F4D50}.Release|Any CPU.Build.0 = Release|Any CPU
{BC5740C3-D439-413C-8CA0-4D0EED720513}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC5740C3-D439-413C-8CA0-4D0EED720513}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC5740C3-D439-413C-8CA0-4D0EED720513}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC5740C3-D439-413C-8CA0-4D0EED720513}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E29C020E-A3FD-4756-ACB3-3828F915EB40} = {926C18AE-808E-4E77-985F-4EF54792D523}
Expand All @@ -141,5 +155,7 @@ Global
{5EAB42A1-4C5B-407A-AE4E-34F608365760} = {E29C020E-A3FD-4756-ACB3-3828F915EB40}
{DD751505-81EC-4B8D-B2A5-FB246DCB68E4} = {E29C020E-A3FD-4756-ACB3-3828F915EB40}
{A2EE3F83-C57C-48B1-A5FE-E573284B6661} = {E29C020E-A3FD-4756-ACB3-3828F915EB40}
{BE7D3C27-91BF-4EC0-A9C8-462B3FC6C9EC} = {926C18AE-808E-4E77-985F-4EF54792D523}
{BC5740C3-D439-413C-8CA0-4D0EED720513} = {BE7D3C27-91BF-4EC0-A9C8-462B3FC6C9EC}
EndGlobalSection
EndGlobal
1 change: 1 addition & 0 deletions NftFaucet/NftFaucet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<ProjectReference Include="..\plugins\upload-plugins\NftFaucet.UploadPlugins.Crust\NftFaucet.UploadPlugins.Crust.csproj" />
<ProjectReference Include="..\plugins\upload-plugins\NftFaucet.UploadPlugins.Infura\NftFaucet.UploadPlugins.Infura.csproj" />
<ProjectReference Include="..\plugins\upload-plugins\NftFaucet.UploadPlugins.NftStorage\NftFaucet.UploadPlugins.NftStorage.csproj" />
<ProjectReference Include="..\plugins\import-plugins\NftFaucet.ImportPlugins.OpenSea\NftFaucet.ImportPlugins.OpenSea.csproj" />
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions NftFaucet/Pages/ImportTokenDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@page "/tokens/import"
@inherits BasicComponent

<PageTitle>Import new token</PageTitle>
<RadzenContent Container="main">
<h3>Select importer</h3>
<CardList Data="@ImporterCards" @bind-SelectedItems="@SelectedImporterIds"/>
<div class="mb-4">
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">ChainID</RadzenText><text style="color: red"> *</text>
<RadzenDropDown TextProperty="Name" ValueProperty="ChainId" Data="@SupportedNetworks" @bind-Value="@Model.ChainId" Class="w-100"/>
</div>
<div class="mb-4">
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">Contract Address</RadzenText><text style="color: red"> *</text>
<RadzenTextBox Placeholder="0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" MaxLength="42" @bind-Value="@Model.ContractAddress" Class="w-100"/>
</div>
<div class="mb-4">
<RadzenText TextStyle="TextStyle.H6" Style="display: inline;">TokenID</RadzenText><text style="color: red"> *</text>
<RadzenTextBox Placeholder="0" MaxLength="78" @bind-Value="@Model.TokenId" Class="w-100"/>
</div>
<div class="row">
<div class="col-md-12 text-right">
<RadzenButton Text="Cancel" Click="@(args => DialogService.Close())" ButtonStyle="ButtonStyle.Secondary" Disabled="IsImporting" Style="width: 120px" Class="mr-1"/>
<RadzenButton Text="Import" Icon="eject" BusyText="Importing..." IsBusy=@IsImporting Click="@(async args => await OnImportPressed())" Disabled="@(SelectedImporter == null || !SelectedImporter.IsConfigured)" Style="width: 180px"/>
</div>
</div>
</RadzenContent>
Loading

0 comments on commit 800cfb3

Please sign in to comment.