-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System; | ||
using System.Collections; | ||
using TezosSDK.Scripts.FileUploaders.IPFS; | ||
using UnityEngine; | ||
|
||
namespace TezosSDK.Scripts.FileUploaders | ||
{ | ||
public abstract class BaseUploader : MonoBehaviour | ||
{ | ||
public string SupportedFileExtensions { get; } = ".jpg, .jpeg, .png"; | ||
|
||
private void Start() | ||
{ | ||
DontDestroyOnLoad(gameObject); | ||
} | ||
} | ||
|
||
public interface IPinataUploader : IBaseUploader | ||
{ | ||
PinataCredentials PinataCredentials { get; set; } | ||
} | ||
|
||
public interface IBaseUploader | ||
{ | ||
string SupportedFileExtensions { get; } | ||
|
||
/// <summary> | ||
/// Upload file that user will select through native menu file picker. | ||
/// </summary> | ||
/// <param name="callback"> | ||
/// Executes after asset uploaded with data address. | ||
/// </param> | ||
IEnumerator UploadFile(Action<string> callback); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace TezosSDK.Scripts.FileUploaders.IPFS | ||
{ | ||
public class PinataCredentials | ||
{ | ||
public string ApiUrl { get; } | ||
public string ApiKey { get; } | ||
|
||
public PinataCredentials(string apiKey) | ||
{ | ||
ApiUrl = "https://api.pinata.cloud/pinning/pinFileToIPFS"; | ||
ApiKey = apiKey; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
mergeInto(LibraryManager.library, { | ||
JsInitPinataUploader: function ( | ||
callbackObjectName, | ||
callbackMethodName, | ||
apiUrl, | ||
apiKey | ||
) { | ||
InitIpfsUploader({ | ||
CallbackObjectName: UTF8ToString(callbackObjectName), | ||
CallbackMethodName: UTF8ToString(callbackMethodName), | ||
ApiUrl: UTF8ToString(apiUrl), | ||
ApiKey: UTF8ToString(apiKey), | ||
}); | ||
}, | ||
|
||
JsInitBase64Uploader: function ( | ||
callbackObjectName, | ||
callbackMethodName | ||
) { | ||
InitBase64Uploader({ | ||
CallbackObjectName: UTF8ToString(callbackObjectName), | ||
CallbackMethodName: UTF8ToString(callbackMethodName) | ||
}); | ||
}, | ||
|
||
JsRequestUserFile: function (extensions) { | ||
FileUploader.RequestUserFile(UTF8ToString(extensions)); | ||
}, | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#if UNITY_EDITOR | ||
using System; | ||
using System.Collections; | ||
using System.IO; | ||
using UnityEditor; | ||
|
||
|
||
namespace TezosSDK.Scripts.FileUploaders.OnChain | ||
{ | ||
public class EditorBase64Uploader : BaseUploader, IBaseUploader | ||
{ | ||
public IEnumerator UploadFile(Action<string> callback) | ||
{ | ||
yield return null; | ||
var imagePath = EditorUtility.OpenFilePanel( | ||
"Select image", | ||
string.Empty, | ||
SupportedFileExtensions | ||
.Replace(".", string.Empty) | ||
.Replace(" ", string.Empty) | ||
); | ||
callback.Invoke(ConvertImageToBase64(imagePath)); | ||
} | ||
|
||
private static string ConvertImageToBase64(string imagePath) | ||
{ | ||
var fileExtension = Path | ||
.GetExtension(imagePath) | ||
.Replace(".", string.Empty) | ||
.ToLower(); | ||
|
||
var imageBytes = File.ReadAllBytes(imagePath); | ||
var base64String = Convert.ToBase64String(imageBytes); | ||
return $"data:image/{fileExtension};base64,{base64String}"; | ||
} | ||
} | ||
} | ||
#endif |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Runtime.InteropServices; | ||
using Logger = TezosSDK.Helpers.Logger; | ||
using UnityEngine; | ||
|
||
namespace TezosSDK.Scripts.FileUploaders.OnChain | ||
{ | ||
public class WebBase64Uploader : BaseUploader, IBaseUploader | ||
{ | ||
public void FileRequestCallback(string path) | ||
{ | ||
WebBase64UploaderHelper.SetResult(path); | ||
} | ||
|
||
public IEnumerator UploadFile(Action<string> callback) | ||
{ | ||
yield return null; | ||
WebBase64UploaderHelper.RequestFile(callback, SupportedFileExtensions); | ||
} | ||
} | ||
|
||
public static class WebBase64UploaderHelper | ||
{ | ||
private static Action<string> _responseCallback; | ||
|
||
public static IBaseUploader GetUploader() | ||
{ | ||
const string callbackObjectName = nameof(WebBase64Uploader); | ||
const string callbackMethodName = nameof(WebBase64Uploader.FileRequestCallback); | ||
|
||
var webUploaderGameObject = GameObject.Find(nameof(WebBase64Uploader)); | ||
var uploader = webUploaderGameObject != null | ||
? webUploaderGameObject.GetComponent<WebBase64Uploader>() | ||
: new GameObject(nameof(WebBase64Uploader)).AddComponent<WebBase64Uploader>(); | ||
|
||
JsInitBase64Uploader( | ||
callbackObjectName, | ||
callbackMethodName); | ||
|
||
return uploader; | ||
} | ||
|
||
public static void RequestFile(Action<string> callback, string extensions) | ||
{ | ||
JsRequestUserFile(extensions); | ||
_responseCallback = callback; | ||
} | ||
|
||
public static void SetResult(string response) | ||
{ | ||
_responseCallback.Invoke(response); | ||
Dispose(); | ||
} | ||
|
||
private static void Dispose() | ||
{ | ||
_responseCallback = null; | ||
} | ||
|
||
[DllImport("__Internal")] | ||
private static extern void JsInitBase64Uploader( | ||
string objectName, | ||
string methodName); | ||
|
||
[DllImport("__Internal")] | ||
private static extern void JsRequestUserFile(string extensions); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using TezosSDK.Scripts.FileUploaders.IPFS; | ||
using TezosSDK.Scripts.FileUploaders.OnChain; | ||
using UnityEngine; | ||
|
||
namespace TezosSDK.Scripts.FileUploaders | ||
{ | ||
public static class UploaderFactory | ||
{ | ||
/// <summary> | ||
/// Cross-platform image uploader to IPFS network via Pinata service. | ||
/// </summary> | ||
/// <param name="apiKey">API key from https://app.pinata.cloud/developers/api-keys</param> | ||
public static IBaseUploader GetPinataUploader(string apiKey) | ||
{ | ||
IPinataUploader uploader = null; | ||
|
||
#if UNITY_WEBGL && !UNITY_EDITOR | ||
uploader = WebPinataUploaderHelper.GetUploader(apiKey); | ||
#elif UNITY_EDITOR | ||
var editorUploaderGameObject = GameObject.Find(nameof(EditorPinataUploader)); | ||
uploader = editorUploaderGameObject != null | ||
? editorUploaderGameObject.GetComponent<EditorPinataUploader>() | ||
: new GameObject(nameof(EditorPinataUploader)).AddComponent<EditorPinataUploader>(); | ||
uploader.PinataCredentials = new PinataCredentials(apiKey); | ||
#endif | ||
return uploader; | ||
} | ||
|
||
public static IBaseUploader GetOnchainUploader() | ||
{ | ||
IBaseUploader uploader = null; | ||
|
||
#if UNITY_WEBGL && !UNITY_EDITOR | ||
uploader = WebBase64UploaderHelper.GetUploader(); | ||
#elif UNITY_EDITOR | ||
var editorUploaderGameObject = GameObject.Find(nameof(EditorBase64Uploader)); | ||
uploader = editorUploaderGameObject != null | ||
? editorUploaderGameObject.GetComponent<EditorBase64Uploader>() | ||
: new GameObject(nameof(EditorBase64Uploader)).AddComponent<EditorBase64Uploader>(); | ||
#endif | ||
return uploader; | ||
} | ||
} | ||
} |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import BaseFileUploader from "./BaseFileUploader"; | ||
|
||
class Base64Uploader extends BaseFileUploader { | ||
async FileReceived(file: File) { | ||
window.unityInstance.SendMessage( | ||
this.Config.CallbackObjectName, | ||
this.Config.CallbackMethodName, | ||
await this.СonvertImageToBase64(file) | ||
); | ||
} | ||
|
||
СonvertImageToBase64(file: File): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
const reader = new FileReader(); | ||
|
||
reader.onloadend = () => { | ||
if (typeof reader.result === "string") { | ||
resolve(reader.result); | ||
} else { | ||
reject(new Error("Failed to convert image to base64.")); | ||
} | ||
}; | ||
|
||
reader.onerror = (error) => { | ||
reject(error); | ||
}; | ||
|
||
reader.readAsDataURL(file); | ||
}); | ||
} | ||
} | ||
|
||
export default Base64Uploader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { BaseFileUploaderType, BaseUploaderConfig } from "./Types"; | ||
|
||
abstract class BaseFileUploader implements BaseFileUploaderType { | ||
FileUploaderDomElement: HTMLInputElement; | ||
Config: BaseUploaderConfig; | ||
|
||
Init(config: BaseUploaderConfig) { | ||
this.Config = config; | ||
|
||
this.FileUploaderDomElement = document.getElementById( | ||
"fileuploader" | ||
) as HTMLInputElement; | ||
|
||
if (!this.FileUploaderDomElement) { | ||
this.FileUploaderDomElement = document.createElement("input"); | ||
this.FileUploaderDomElement.setAttribute("style", "display:none;"); | ||
this.FileUploaderDomElement.setAttribute("type", "file"); | ||
this.FileUploaderDomElement.setAttribute("id", "fileuploader"); | ||
this.FileUploaderDomElement.setAttribute("class", "nonfocused"); | ||
document | ||
.getElementsByTagName("body")[0] | ||
.appendChild(this.FileUploaderDomElement); | ||
|
||
this.FileUploaderDomElement.onchange = (event: Event) => { | ||
const { files }: HTMLInputElement = event.target as HTMLInputElement; | ||
|
||
if (files.length === 0) { | ||
this.ResetFileUploader(); | ||
} else { | ||
this.FileReceived(files[0]); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
abstract FileReceived(file: File): void; | ||
|
||
ResetFileUploader() { | ||
this.FileUploaderDomElement?.setAttribute("class", "nonfocused"); | ||
} | ||
|
||
RequestUserFile(fileExtensions: string) { | ||
if (this.FileUploaderDomElement === null) this.Init(this.Config); | ||
|
||
if (fileExtensions !== null || fileExtensions.match(/^ *$/) === null) | ||
this.FileUploaderDomElement.setAttribute("accept", fileExtensions); | ||
|
||
this.FileUploaderDomElement.setAttribute("class", "focused"); | ||
this.FileUploaderDomElement.click(); | ||
} | ||
} | ||
|
||
export default BaseFileUploader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { IpfsUploaderConfig, IpfsUploaderType } from "./Types"; | ||
|
||
import BaseFileUploader from "./BaseFileUploader"; | ||
|
||
class IpfsUploader extends BaseFileUploader implements IpfsUploaderType { | ||
Config: IpfsUploaderConfig; | ||
|
||
Init(config: IpfsUploaderConfig) { | ||
super.Init(config); | ||
this.Config = config; | ||
} | ||
|
||
async FileReceived(file: File) { | ||
const formData = new FormData(); | ||
formData.append("file", file, file.name); | ||
const options = { | ||
method: "POST", | ||
body: formData, | ||
|
||
headers: { | ||
Authorization: `Bearer ${this.Config.ApiKey}`, | ||
}, | ||
}; | ||
|
||
try { | ||
const request = await fetch(this.Config.ApiUrl, options); | ||
const data: string = await request.text(); | ||
|
||
window.unityInstance.SendMessage( | ||
this.Config.CallbackObjectName, | ||
this.Config.CallbackMethodName, | ||
data | ||
); | ||
} catch (error) { | ||
console.error( | ||
`Error during uploading file to ${this.Config.ApiUrl}\n${error}` | ||
); | ||
} | ||
|
||
this.ResetFileUploader(); | ||
} | ||
} | ||
|
||
export default IpfsUploader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
interface IpfsUploaderType extends BaseFileUploaderType { | ||
Config: IpfsUploaderConfig; | ||
Init(config: IpfsUploaderConfig): void; | ||
} | ||
|
||
interface IpfsUploaderConfig extends BaseUploaderConfig { | ||
ApiUrl: string; | ||
ApiKey: string; | ||
} | ||
|
||
interface IpfsResponse { | ||
IpfsHash: string; | ||
PinSize: number; | ||
Timestamp: Date; | ||
isDuplicate: boolean; | ||
} | ||
|
||
interface BaseFileUploaderType { | ||
FileUploaderDomElement: HTMLInputElement; | ||
Config: BaseUploaderConfig; | ||
Init(config: BaseUploaderConfig): void; | ||
RequestUserFile(fileExtensions: string): void; | ||
ResetFileUploader(): void; | ||
} | ||
|
||
interface BaseUploaderConfig { | ||
CallbackObjectName: string; | ||
CallbackMethodName: string; | ||
} | ||
|
||
export { | ||
BaseFileUploaderType, | ||
BaseUploaderConfig, | ||
IpfsResponse, | ||
IpfsUploaderConfig, | ||
IpfsUploaderType, | ||
}; |
This file was deleted.
This file was deleted.