Add IPFS upload implementation

This commit is contained in:
Ivan Yaremenchuk 2022-08-30 21:54:12 -05:00
parent a574a67275
commit 409892b802
7 changed files with 74 additions and 12 deletions

View File

@ -12,9 +12,11 @@
<PackageReference Include="CSharpFunctionalExtensions" Version="2.33.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="MimeTypeMapOfficial" Version="1.0.17" />
<PackageReference Include="Nethereum.ABI" Version="4.8.0" />
<PackageReference Include="Nethereum.JsonRpc.Client" Version="4.8.0" />
<PackageReference Include="Radzen.Blazor" Version="3.20.4" />
<PackageReference Include="RestEase" Version="1.5.7" />
<PackageReference Include="Solana.Metaplex" Version="1.3.0" />
</ItemGroup>

View File

@ -1,5 +1,6 @@
using Microsoft.JSInterop;
using Microsoft.AspNetCore.Components;
using MimeTypes;
using NftFaucetRadzen.Models;
using NftFaucetRadzen.Plugins;
using Radzen;
@ -43,13 +44,25 @@ public partial class CreateTokenPage
Image = new TokenMedia
{
FileName = Model.FileName,
FileSize = Model.FileSize!.Value,
FileType = DetermineFileType(Model.FileName),
FileData = Model.FileData,
FileSize = Model.FileSize!.Value,
},
};
DialogService.Close(token);
}
private string DetermineFileType(string fileName)
{
var extension = fileName.Split('.', StringSplitOptions.RemoveEmptyEntries).Last();
if (!MimeTypeMap.TryGetMimeType(extension, out var mimeType))
{
return "application/octet-stream";
}
return mimeType;
}
private bool IsValid()
{
if (string.IsNullOrWhiteSpace(Model.Name))

View File

@ -2,7 +2,8 @@ namespace NftFaucetRadzen.Plugins;
public interface ITokenMedia
{
public string FileData { get; }
public string FileName { get; }
public string FileType { get; }
public string FileData { get; }
public long FileSize { get; }
}

View File

@ -2,7 +2,8 @@ namespace NftFaucetRadzen.Plugins;
public class TokenMedia : ITokenMedia
{
public string FileData { get; set; }
public string FileName { get; set; }
public string FileType { get; set; }
public string FileData { get; set; }
public long FileSize { get; set; }
}

View File

@ -0,0 +1,14 @@
using System.Net.Http.Headers;
using RestEase;
namespace NftFaucetRadzen.Plugins.UploadPlugins.InfuraDedicatedGateway;
[BaseAddress("https://ipfs.infura.io:5001")]
public interface IInfuraIpfsApiClient
{
[Header("Authorization")]
public AuthenticationHeaderValue Auth { get; set; }
[Post("api/v0/add")]
Task<UploadResponse> UploadFile([Body] MultipartContent content);
}

View File

@ -0,0 +1,8 @@
namespace NftFaucetRadzen.Plugins.UploadPlugins.InfuraDedicatedGateway;
public class UploadResponse
{
public string Name { get; set; }
public string Hash { get; set; }
public string Size { get; set; }
}

View File

@ -1,4 +1,7 @@
using System.Net.Http.Headers;
using System.Text;
using CSharpFunctionalExtensions;
using RestEase;
namespace NftFaucetRadzen.Plugins.UploadPlugins.InfuraDedicatedGateway.Uploaders;
@ -10,6 +13,8 @@ public class InfuraDedicatedGatewayUploader : IUploader
public string ImageName { get; } = "infura_black.svg";
public bool IsSupported { get; } = true;
public bool IsInitialized { get; private set; } = false;
private Uri DedicatedGatewayUrl { get; set; }
public IReadOnlyCollection<ConfigurationItem> GetConfigurationItems()
=> new[]
@ -50,20 +55,38 @@ public class InfuraDedicatedGatewayUploader : IUploader
return Result.Failure("Invalid url host. Expected host ending with '.infura-ipfs.io'");
}
DedicatedGatewayUrl = url;
IsInitialized = true;
return Result.Success();
}
public async Task<Result<Uri>> Upload(IToken token)
{
await Task.Delay(TimeSpan.FromSeconds(2));
if (Random.Shared.Next(1, 101) > 80)
{
return Result.Success(new Uri("https://example.com"));
}
else
{
return Result.Failure<Uri>("FAKE UPLOAD FAILURE");
}
var uploadClient = RestClient.For<IInfuraIpfsApiClient>();
var auth = Convert.ToBase64String(Encoding.ASCII.GetBytes("<project-id>:<project-secret>"));
uploadClient.Auth = new AuthenticationHeaderValue("Basic", auth);
var fileUploadRequest = ToMultipartContent(token.Image.FileName, token.Image.FileType, token.Image.FileData);
var response = await uploadClient.UploadFile(fileUploadRequest);
var uri = new Uri("ipfs://" + response.Hash);
return uri;
}
private MultipartContent ToMultipartContent(string fileName, string fileType, string fileData)
{
var content = new MultipartFormDataContent();
var bytes = Base64DataToBytes(fileData);
var imageContent = new ByteArrayContent(bytes);
imageContent.Headers.Add("Content-Type", fileType);
content.Add(imageContent, "\"file\"", $"\"{fileName}\"");
return content;
}
private byte[] Base64DataToBytes(string fileData)
{
var index = fileData.IndexOf(';');
var encoded = fileData.Substring(index + 8);
return Convert.FromBase64String(encoded);
}
}