From c2ce53beb35fedeca1ec37e12290b9749bd7e600 Mon Sep 17 00:00:00 2001 From: "sz.sahaj" <43649755+saszer@users.noreply.github.com> Date: Wed, 7 Sep 2022 20:59:49 +1000 Subject: [PATCH] feat: New Feature : Transfer NFT --- Editor/FeatureSpawner.cs | 7 + Editor/Resources/c_product_update 1.psd | 3 + Editor/Resources/c_product_update 1.psd.meta | 134 ++++++++++ Editor/Resources/c_transferNFT.psd | 3 + Editor/Resources/c_transferNFT.psd.meta | 134 ++++++++++ Editor/Transfer_NFT_Editor1.cs | 38 +++ Editor/Transfer_NFT_Editor1.cs.meta | 11 + Runtime/Burn_NFT.cs | 2 +- Runtime/Internal/PortConstants.cs | 2 + Runtime/Transfer_NFT.cs | 249 +++++++++++++++++++ Runtime/Transfer_NFT.cs.meta | 11 + 11 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 Editor/Resources/c_product_update 1.psd create mode 100644 Editor/Resources/c_product_update 1.psd.meta create mode 100644 Editor/Resources/c_transferNFT.psd create mode 100644 Editor/Resources/c_transferNFT.psd.meta create mode 100644 Editor/Transfer_NFT_Editor1.cs create mode 100644 Editor/Transfer_NFT_Editor1.cs.meta create mode 100644 Runtime/Transfer_NFT.cs create mode 100644 Runtime/Transfer_NFT.cs.meta diff --git a/Editor/FeatureSpawner.cs b/Editor/FeatureSpawner.cs index 16cfa03..cf945d0 100644 --- a/Editor/FeatureSpawner.cs +++ b/Editor/FeatureSpawner.cs @@ -31,6 +31,13 @@ static void Burn_NFT() { Selection.activeGameObject= new GameObject(PortConstants.FeatureName_Burn_NFT).AddComponent().gameObject; } + + [MenuItem(PortConstants.BaseFeatureSpawnerMenu + PortConstants.FeatureName_Transfer_NFT)] + [MenuItem(GameObjMenu + PortConstants.FeatureName_Transfer_NFT)] + static void Transfer_NFT() + { + Selection.activeGameObject= new GameObject(PortConstants.FeatureName_Transfer_NFT).AddComponent().gameObject; + } [MenuItem(PortConstants.BaseFeatureSpawnerMenu + PortConstants.FeatureName_Update_NFT)] [MenuItem(GameObjMenu + PortConstants.FeatureName_Update_NFT)] diff --git a/Editor/Resources/c_product_update 1.psd b/Editor/Resources/c_product_update 1.psd new file mode 100644 index 0000000..444ef01 --- /dev/null +++ b/Editor/Resources/c_product_update 1.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42f18d2a79aa382192950f2fe2c5b7adbf5903893f61110bb498825e6365e42f +size 226933 diff --git a/Editor/Resources/c_product_update 1.psd.meta b/Editor/Resources/c_product_update 1.psd.meta new file mode 100644 index 0000000..070fe89 --- /dev/null +++ b/Editor/Resources/c_product_update 1.psd.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 5e5b98bd5e6504646b35d07034897fb7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Resources/c_transferNFT.psd b/Editor/Resources/c_transferNFT.psd new file mode 100644 index 0000000..afef86a --- /dev/null +++ b/Editor/Resources/c_transferNFT.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0781f20995a899d61684040d366f881299fb331d273efb3e0bd2261cb2257239 +size 2538791 diff --git a/Editor/Resources/c_transferNFT.psd.meta b/Editor/Resources/c_transferNFT.psd.meta new file mode 100644 index 0000000..a07ebaa --- /dev/null +++ b/Editor/Resources/c_transferNFT.psd.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: ff2c7b34c7ef7c241a87868c5bd08e5f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Transfer_NFT_Editor1.cs b/Editor/Transfer_NFT_Editor1.cs new file mode 100644 index 0000000..8b5c2f8 --- /dev/null +++ b/Editor/Transfer_NFT_Editor1.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +namespace NFTPort.Editor +{ + using UnityEditor; + using Internal; + + [CustomEditor(typeof(Transfer_NFT))] + public class Transfer_NFT_Editor : Editor + { + public override void OnInspectorGUI() + { + + Transfer_NFT myScript = (Transfer_NFT)target; + + + Texture banner = Resources.Load("c_transferNFT"); + GUILayout.BeginHorizontal(); + GUILayout.Box(banner); + GUILayout.EndHorizontal(); + + if (GUILayout.Button("Transfer NFT", GUILayout.Height(45))) + { + PortUser.SetFromEditorWin(); + myScript.Run(); + } + + if(GUILayout.Button("View Documentation", GUILayout.Height(25))) + Application.OpenURL(PortConstants.Docs_Transfer_NFT); + + EditorGUILayout.HelpBox("Transferring is possible only if the token is owned by the contract owner and the token has not been transferred/sold yet.", MessageType.Info); + + + DrawDefaultInspector(); + } + } +} + diff --git a/Editor/Transfer_NFT_Editor1.cs.meta b/Editor/Transfer_NFT_Editor1.cs.meta new file mode 100644 index 0000000..e4f3186 --- /dev/null +++ b/Editor/Transfer_NFT_Editor1.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 869fdedbf56927a45b8835c3cb7d9cfe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Burn_NFT.cs b/Runtime/Burn_NFT.cs index 9dd3020..9d880e6 100644 --- a/Runtime/Burn_NFT.cs +++ b/Runtime/Burn_NFT.cs @@ -229,7 +229,7 @@ IEnumerator CallAPIProcess(CustomNFT nft) afterSuccess.Invoke(); if(debugErrorLog) - Debug.Log($"NFTPort | NFT Update Success (⌐■_■) : at: {minted.transaction_external_url}" ); + Debug.Log($"NFTPort | NFT Burn Success (⌐■_■) : at: {minted.transaction_external_url}" ); } request.Dispose(); diff --git a/Runtime/Internal/PortConstants.cs b/Runtime/Internal/PortConstants.cs index 0008a8b..1295e9d 100644 --- a/Runtime/Internal/PortConstants.cs +++ b/Runtime/Internal/PortConstants.cs @@ -23,6 +23,7 @@ public static class PortConstants public const string Txn_Collection = "https://docs.nftport.xyz/docs/nftport/ZG9jOjgzODU5NDUx-transaction-data-collection-contract"; public const string Docs_Update_NFT = "https://docs.nftport.xyz/docs/nftport/ZG9jOjg2MTE3MTg4-customizable-minted-update-nft"; + public const string Docs_Transfer_NFT = "https://docs.nftport.xyz/docs/nftport/ZG9jOjg2MTE3MTg4-customizable-minted-update-nft"; public const string Docs_Burn_NFT = "https://docs.nftport.xyz/docs/nftport/ZG9jOjg2MTE3MTg4-customizable-minted-update-nft"; @@ -59,6 +60,7 @@ public static class PortConstants public const string FeatureName_Txn_Collection = "Transaction Data | Collection"; public const string FeatureName_Update_NFT = "Customizable minted | Update NFT"; public const string FeatureName_Burn_NFT = "Customizable minted | Burn NFT"; + public const string FeatureName_Transfer_NFT = "Customizable minted | Transfer NFT"; } } diff --git a/Runtime/Transfer_NFT.cs b/Runtime/Transfer_NFT.cs new file mode 100644 index 0000000..ceb62b0 --- /dev/null +++ b/Runtime/Transfer_NFT.cs @@ -0,0 +1,249 @@ +using System.Collections; +using Newtonsoft.Json; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.Networking; + +namespace NFTPort +{ using Internal; + + + /// + /// Transfer NFT minted via customizable minting. + /// + /// + [AddComponentMenu(PortConstants.BaseComponentMenu+PortConstants.FeatureName_Transfer_NFT)] + [ExecuteAlways] + [HelpURL(PortConstants.Docs_Transfer_NFT)] + public class Transfer_NFT : MonoBehaviour + { + public enum Chains + { + polygon, + rinkeby + } + + private class CustomNFT + { + public string chain; + public string contract_address; + public string token_id; + public string transfer_to_address; + } + + + #region Parameter Defines + + [SerializeField] + private Chains _chain = Chains.polygon; + + [SerializeField] private string _contract_address = "Enter previously deployed contract address using deploy feature"; + [SerializeField] [Tooltip("Token ID of NFT to update.")] private string _token_id = "0"; + [SerializeField] private string _transfer_to_address = "Wallet address to which the NFT will be transferred."; + + [Space(20)] + //[Header("Called When API call starts")] + public UnityEvent OnRequestStarted; + //[Header("Called After Successful API call")] + public UnityEvent afterSuccess; + //[Header("Called After Error API call")] + public UnityEvent afterError; + + [Header("Run Component when this Game Object is Set Active")] + [SerializeField] private bool onEnable = false; + public bool debugErrorLog = true; + public bool debugLogRawApiResponse = false; + + [Header("Response after successful mint:")] + public Minted_model minted; + + private UnityAction OnErrorAction; + private UnityAction OnCompleteAction; + + private string RequestUriInit = "https://api.nftport.xyz/v0/mints/transfers"; + private string WEB_URL; + private string _apiKey; + private bool destroyAtEnd = false; + + #endregion + + + private void Awake() + { + PortUser.Initialise(); + _apiKey = PortUser.GetUserApiKey(); + + } + + private void OnEnable() + { + if (onEnable & Application.isPlaying) + { + PortUser.SetFromOnEnable(); + Run(); + } + + } + + /// + /// Initialize creates a gameobject and assings this script as a component. This must be called if you are not refrencing the script any other way and it doesn't already exists in the scene. + /// + /// Optional bool parameter can set to false to avoid Spawned GameObject being destroyed after the Api process is complete. + public static Transfer_NFT Initialize(bool destroyAtEnd = true) + { + var _this = new GameObject(PortConstants.FeatureName_Transfer_NFT).AddComponent(); + _this.destroyAtEnd = destroyAtEnd; + _this.onEnable = false; + _this.debugErrorLog = false; + return _this; + } + + /// + /// Set NFT Parameters ≧◔◡◔≦ . + /// + /// Previously deployed contract address of this user. + /// Int Token ID for the NFT + /// Address to which NFT will be transfered to + + public Transfer_NFT SetParameters(string contract_address = null, string token_id = null, string transfer_to_address = null) + { + if(contract_address!=null) + _contract_address = contract_address; + if(transfer_to_address!=null) + _transfer_to_address = transfer_to_address; + if(token_id!=null) + _token_id = token_id; + + return this; + } + + /// + /// Set Blockchain + /// + /// Choose from available 'Chains' enum + public Transfer_NFT SetChain(Chains chain) + { + this._chain = chain; + return this; + } + + /// + /// Action on successful API Fetch. + /// + /// Use: .OnComplete(model=> Model = model) , where Model = Minted_model; + /// Minted_model + public Transfer_NFT OnComplete(UnityAction action) + { + this.OnCompleteAction = action; + return this; + } + + /// + /// Action on Error(⊙.◎) + /// + /// string. + /// Information on Error as string text. + public Transfer_NFT OnError(UnityAction action) + { + this.OnErrorAction = action; + return this; + } + + /// + /// Run (ɔ◔‿◔)ɔ + /// + public Minted_model Run() + { + WEB_URL = BuildUrl(); + StopAllCoroutines(); + StartCoroutine(CallAPIProcess(CreateProductNFT())); + return minted; + } + + CustomNFT CreateProductNFT() + { + var nft = new CustomNFT(); + nft.chain = _chain.ToString().ToLower(); + nft.contract_address = _contract_address; + nft.token_id = _token_id; + nft.transfer_to_address = _transfer_to_address; + return nft; + } + + string BuildUrl() + { + WEB_URL = RequestUriInit; + + return WEB_URL; + } + + + IEnumerator CallAPIProcess(CustomNFT nft) + { + + if(debugErrorLog) + Debug.Log("Transfer NFT ⊂(▀¯▀⊂) | " + _contract_address + " tokenID: " + _token_id + " on chain: " + _chain ); + + string json = JsonConvert.SerializeObject( + nft, + new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore + }); + if(debugErrorLog) + Debug.Log(json); + + byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json); + var request = new UnityWebRequest(WEB_URL, "PUT"); + + request.uploadHandler = (UploadHandler) new UploadHandlerRaw(jsonToSend); + request.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer(); + + //headers + request.SetRequestHeader("Content-Type", "application/json"); + request.SetRequestHeader("source", PortUser.GetSource()); + request.SetRequestHeader("Authorization", _apiKey); + + //Make request + if(OnRequestStarted!=null) + OnRequestStarted.Invoke(); + yield return request.SendWebRequest(); + string jsonResult = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data); + + + if(debugLogRawApiResponse) + Debug.Log(jsonResult); + + if (request.error != null) + { + if(OnErrorAction!=null) + OnErrorAction($"Null data. Response code: {request.responseCode}. Result {jsonResult}"); + if(debugErrorLog) + Debug.Log($"(⊙.◎) Null data. Response code: {request.responseCode}. Result {jsonResult}"); + if(afterError!=null) + afterError.Invoke(); + } + else + { + //Fill Data Model from received class + minted = JsonConvert.DeserializeObject(jsonResult); + + if(OnCompleteAction!=null) + OnCompleteAction.Invoke(minted); + + if(afterSuccess!=null) + afterSuccess.Invoke(); + + if(debugErrorLog) + Debug.Log($"NFTPort | NFT Transfer Success (⌐■_■) : at: {minted.transaction_external_url}" ); + } + + request.Dispose(); + if (destroyAtEnd) + { + Destroy(this.gameObject); + } + } + } +} diff --git a/Runtime/Transfer_NFT.cs.meta b/Runtime/Transfer_NFT.cs.meta new file mode 100644 index 0000000..6b3527d --- /dev/null +++ b/Runtime/Transfer_NFT.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3598b7082d6cc1b468eb35f96a467a0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 5e5b98bd5e6504646b35d07034897fb7, type: 3} + userData: + assetBundleName: + assetBundleVariant: