{"id":19248213,"url":"https://github.com/neftyblocks/nefty-blends-unity","last_synced_at":"2026-05-18T03:34:03.041Z","repository":{"id":180642346,"uuid":"598036436","full_name":"neftyblocks/nefty-blends-unity","owner":"neftyblocks","description":"Proof of concept of a Unity Project that interacts with the NeftyBlocks blends contract.","archived":false,"fork":false,"pushed_at":"2023-06-28T10:00:39.000Z","size":52835,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-03T05:44:37.441Z","etag":null,"topics":["antelope","atomicassets","crafting","unity"],"latest_commit_sha":null,"homepage":"https://unity-sdk.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neftyblocks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-06T09:02:55.000Z","updated_at":"2023-10-04T20:42:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"e4f48070-7df1-480d-b996-5302e4413b47","html_url":"https://github.com/neftyblocks/nefty-blends-unity","commit_stats":null,"previous_names":["neftyblocks/nefty-blends-unity"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/neftyblocks/nefty-blends-unity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neftyblocks%2Fnefty-blends-unity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neftyblocks%2Fnefty-blends-unity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neftyblocks%2Fnefty-blends-unity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neftyblocks%2Fnefty-blends-unity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neftyblocks","download_url":"https://codeload.github.com/neftyblocks/nefty-blends-unity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neftyblocks%2Fnefty-blends-unity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33163754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"online","status_checked_at":"2026-05-18T02:00:06.436Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["antelope","atomicassets","crafting","unity"],"created_at":"2024-11-09T18:07:02.224Z","updated_at":"2026-05-18T03:34:03.019Z","avatar_url":"https://github.com/neftyblocks.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\nThis repository aims to be a valuable resource for developers. It offers information and inspiration for building tools in the WAX ecosystem, improving the quality of products. The plugin is created in Unity and is designed to be easily customized, allowing third parties to integrate it into their own Unity projects. The main goal is to increase development opportunities, promote decentralization, and contribute to the wider blockchain ecosystem.\n\nIncluded within the GitHub repository is a demonstration of NeftyBlocks blending feature. The demo includes a step-by-step guide on how to log in and submit smart contract transactions directly to the blockchain and many other features. The transaction submission is facilitated by a JavaScript (JS) wrapper, which serves as a communication bridge between C# and JS. The repository also provides instructions on how to deploy projects into a WebGL environment and also how to test them and deploy.\n\n## 🔑 Prerequisites\n\n- Browserify\n- Git\n- Npm\n- Node.js\n- Unity Hub\n\n## 🔧 Installing\n\n**For windows:**\n\nStep 1: **Clone the Repository**\n\n_To get started, there are two options available:_\n\n1. **Clone the Repository**: Use the \"Clone\" command to create a local copy of the current repository. You can do this by executing the following command in your preferred terminal:\n\n`git clone https://github.com/neftyblocks/unity-sdk.git`\n\n2.  **Download the .zip File**: Alternatively, you can choose to download the repository as a .zip file. Simply click on the \"Code\" button and select \"Download ZIP\" from the dropdown menu.\n\nChoose the method that suits your preference to obtain a copy of the repository for further use.\n\nStep 2: **Open the Project in Unity Hub**\n\nAfter downloading the project, **open** it using **Unity Hub**:\n\n1.  Click on \"**Open**\" in **Unity Hub**.\n2.  **Locate** the project within the designated folder where you have saved it.\n\nIf you encounter a **warning** message indicating that you need to install the appropriate Unity version, follow the prompt to install the required version. Additionally, make sure to **include** the **WebGL Build Support** by adding it as a module during installation.\n\nStep 4: **Build the Project for WebGL**\n\nOnce you've launched the project, follow these steps to build it for WebGL:\n\n1.  Click on **\"File\"** and choose \"**Build Settings.**\"\n2.  In the Build Settings window, locate the Platform option and **switch** it to WebGL.\n3.  Ensure that the selected scene is added at the top in the \"Scenes in Build\" list.\n4.  Finally, click on the \"**Build**\" button to generate the WebGL build within the **WebGL-Build folder**.\n\nThis process will enable you to experience the plugin in a browser environment.\n\nStep 5: **Finalize the Installation**\n\nTo complete the installation, follow these steps:\n\n1.  Navigate to the \"webgl-build\" folder after you have finished building the project.\n2.  Within the \"webgl-build\" folder, locate the existing \"index.html\" file.\n3.  Replace the existing \"index.html\" file with the one located in a separate folder named \"HTML\".\n\n## 📖 User guide\n\nOnce the plugin is built and running in the local environment, you can access the login screen. From there, you have two options: you can either log in with **Anchor** or **Wax Cloud Wallet**. These options are made possible through the use of forked UAL dependencies by NeftyBlocks. Additionally, the user has the flexibility to select their own RPC endpoint. This allows them to submit transactions and make calls to the \"get_table_rows\" function using the endpoint of their choice.\n![](https://i.ibb.co/xmzY2np/Screenshot-4.png)\n\nAfter the user successfully logs in, they can view their owned NFTs. These NFTs are organized by collection, based on the **Collection Name** set inside the PluginController. To locate the **PluginController**, you can search for it in the **Project Hierarchy**.\n\n![](https://i.ibb.co/fQY4Kcf/Screenshot-13.png)\nFor customization, navigate to the UIController game object within the hierarchy. Inside the inspector, you will find a menu that allows you to define various elements such as colors, button sprites, and wallpapers for the project. Additionally, you have the option to choose the default settings if desired.\n![enter image description here](https://i.ibb.co/whgDcRC/Screenshot-2.png)\n\nPlease note that before proceeding with customization, it is important to select the desired colors and wallpapers. Once you have made your selections, remember to press Ctrl + S to save the changes. Afterward, you can run the plugin either in the browser or within Unity itself to apply the customized settings.\n\nFurthermore, you can **view blends** by clicking the **\"Blends\"** button. These blends are based on the **PluginController**, which sets the **Collection Name.** By selecting a specific collection, you can retrieve blends associated with it.\n\nBlends **may have protection** measures in place. If a blend is protected, it can be either protected by a **whitelist** or by **proof of ownership**. If the user passes the protection requirements, they will be able to blend the NFT.\n\nIf a blend does not have any protection, eligible users can submit the transaction to the blockchain. The required ingredients for the blend will be automatically selected for you. However, you also have the option to manually change the asset in the ingredient slot by clicking on it.\n\nBlends operate using **fungible tokens, collections, schemas, attributes**, and **templates**. If the blending process goes smoothly, you will receive a success popup and the resulting NFT will be added to your inventory.\n\n## 📚 Examples\n\nIn this section, I will provide a few examples of techniques that you can use to create your own application based on the approach used in this plugin.\n\n### !! Important Note !!\n\nWhenever changes are made to the JavaScript or HTML files, it is important to follow these steps:\n\n1. Open the terminal and navigate to the Web-GL folder.\n2. Run the following command: `browserify index.mjs -o bundle.js`\n3. This command will update the JavaScript code inside the bundle.\n\nPlease ensure that you execute these steps to keep the JavaScript and HTML files synchronized.\n\n### Example 1: Login\n\nTo ensure proper functionality of the login feature, there are a few libraries that you need. Fortunately, these libraries are already included in the project, so you don't need to add anything. The list of required packages, along with their versions, is as follows:\n\n- \"@nefty/ual-anchor\": \"^0.2.5\"\n- \"@nefty/ual-renderer\": \"^0.1.1\"\n- \"@nefty/ual-wax\": \"^0.2.7\"\n- \"@waxio/waxjs\": \"^1.3.0\"\n\nYou can find these packages in the `WebGL-Build/package.js` file.\n\nThe code snippet provided demonstrates the configuration and initialization of a Universal Authenticator Library (UAL) for a specific application. UAL allows users to authenticate and interact with blockchain-based applications. Here's a breakdown of the code and its functionality\n\n```js\nconst { UALJs } = require(\"@nefty/ual-renderer\");\nconst { Wax } = require(\"@nefty/ual-wax\");\nconst { Anchor } = require(\"@nefty/ual-anchor\");\nconst { JsonRpc } = require(\"eosjs\");\n```\n\nThe above lines import the necessary libraries and classes for UAL, including the UAL renderer, UAL Wax, UAL Anchor, and JsonRpc from the eosjs library.\n\n```js\nconst myCallback = async (arrayOfUsers) =\u003e {\n  window.user = arrayOfUsers[0];\n  window.accountName = await user.getAccountName();\n  window.permission = (await user.requestPermission) || \"active\";\n  myGameInstance.SendMessage(\n    \"LoginEnvironment\",\n    \"LoggedIn\",\n    window.accountName\n  );\n};\n```\n\nThe `myCallback` function is an asynchronous function that handles the authentication process and receives an array of authenticated users as a parameter. Its purpose is to set global variables for the user's account name and permission, and send a success message to a Unity game instance.\n\nThe `myGameInstance` is a separate variable that facilitates communication between Unity and JavaScript. In this example, it refers to an object in the Unity hierarchy called \"LoginEnvironment\". The function calls the \"LoggedIn\" method of the \"LoginEnvironment\" object, passing the `window.accountName` variable as the argument. This variable represents the account name of the user who has just logged in.\n\n```js\nconst myChain = {\n  chainId: \"1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4\",\n  rpcEndpoints: [\n    {\n      protocol: \"https\",\n      host: \"wax.greymass.com\",\n      port: \"443\",\n    },\n  ],\n};\n```\n\nThe `myChain` object is responsible for configuring the blockchain network. It allows you to specify the chain ID and the RPC endpoint. If you want to use a different Antelope Chain, you would need to update the `chainId` and `rpcEndpoints` properties accordingly.\n\nIf you decide to use the WAX blockchain, you can modify the endpoint to any preferred endpoint available within the following link: [https://wax.antelope.tools/endpoints](https://wax.antelope.tools/endpoints). It's important to note that each endpoint may have its own limitations, so it's recommended to double-check the endpoint in case any issues arise.\n\n```js\nconst myAppRoot = {\n  containerElement: document.getElementById(\"ual-div\"),\n};\n\nconst ual = new UALJs(\n  myCallback,\n  [myChain],\n  myAppName,\n  [wax, anchor],\n  myAppRoot\n);\n\nual.init();\n```\n\nThe code initializes the UALJs library by following these steps:\n\n1. The `myAppRoot` object is created to specify the container element for the UAL interface. In this case, the container element is an HTML element with the ID \"ual-div\".\n\n2. An instance of UALJs is created, passing the following parameters: `myCallback` function, `myChain` configuration, `myAppName`, an array of UAL providers (`Wax` and `Anchor`), and the `myAppRoot` object.\n\n3. Finally, the UAL is initialized, which triggers the authentication process and sets up the user interface for interaction with the blockchain.\n\nTo ensure the proper initialization of UAL, you need to include the following line of code in the HTML body of your `WebGL-Build/index.html` file:\n\n```html\n\u003cdiv style=\"display: none\" id=\"ual-div\"\u003e\u003c/div\u003e\n```\n\nThis line of code adds a hidden `\u003cdiv\u003e` element with the ID \"ual-div\", serving as the container for the UAL interface.\n\n```js\nwindow.wax = wax;\nwindow.anchor = anchor;\nwindow.rpcEndpoint = rpcEndpoint;\nwindow.ual = ual;\nwindow.accountName = accountName;\nwindow.permission = permission;\n```\n\nThese global variables can be accessed and utilized throughout the codebase, allowing different parts of the application to interact with the UAL providers, blockchain endpoint, and user-related information.\n\nIn the Unity code, there is a specific folder structure to follow. The `WrapperJS.jslib` file should be placed within the `Assets/Scripts/Plugins` directory. This file contains JavaScript methods that can be called from Unity.\n\nTo integrate these JavaScript methods into Unity, you would typically have a dedicated controller. This controller would handle the button click events and call the appropriate JavaScript method through the `WrapperJS.jslib`.\n\nFor example, let's say you have a `LoginController` that is attached to a button object. When the button is pressed, it would execute a method in the `LoginController` such as `sendTransactionJS.LoginAnchor()`. This method would internally call the JavaScript method associated with it.\n\nIn C#, you might have a declaration like this:\n\n```csharp\n[DllImport(\"__Internal\")]\nprivate static extern void LoginAnchorJS();\n\npublic void LoginAnchor()\n{\n\t LoginAnchorJS();\n}\n```\n\nThe corresponding JavaScript method in `WrapperJS.jslib` would be defined as follows:\n\n```js\nmergeInto(LibraryManager.library, {\n  LoginAnchorJS: async function () {\n    ual.loginUser(anchor);\n  },\n});\n```\n\nThe `LoginAnchorJS` JavaScript method utilizes the `ual.loginUser()` function to perform certain actions or operations associated with logging in using the `anchor` parameter.\n\nBy following this structure and calling the appropriate methods, you can seamlessly execute JavaScript functionality from within Unity, enabling interaction between the two environments.\n\n### Example 2: Submitting transactions\n\nWhen submitting transactions, the process is similar to logging in, but there are a few nuances to keep in mind. In the case of this plugin, you should have a dedicated controller for a specific function, which in this case would be the `BlendController`. If the conditions are met, you would internally call the associated JavaScript method.\n\nThe corresponding JavaScript method in `WrapperJS.jslib` is defined as follows:\n\n```js\nSubmitBlend: async function (\n    blend_id,\n    asset_ids,\n    contractName,\n    tokenSymbol,\n    tokenQuantity,\n    ftCount,\n    assetCount\n  ) {\n    let asset_array = [];\n    let contract_names = [];\n    let token_quantities = [];\n    let token_symbols = [];\n    let actions = [];\n\n    for (var i = 0; i \u003c ftCount; i++) {\n      contract_names.push(UTF8ToString(HEAP32[(contractName + i * 4) \u003e\u003e 2]));\n      token_quantities.push(UTF8ToString(HEAP32[(tokenQuantity + i * 4) \u003e\u003e 2]));\n      token_symbols.push(UTF8ToString(HEAP32[(tokenSymbol + i * 4) \u003e\u003e 2]));\n    }\n\n    for (var i = 0; i \u003c assetCount; i++) {\n      asset_array.push(UTF8ToString(HEAP32[(asset_ids + i * 4) \u003e\u003e 2]));\n    }\n\n    for (let i = 0; i \u003c contract_names.length; i++) {\n      actions.push(OpenBalance(token_symbols[i]));\n      actions.push(TransferToken(contract_names[i], token_quantities[i]));\n    }\n\n    if (assetCount != 0) {\n      actions.push(AnnounceDeposit(blend_id, asset_array, assetCount));\n      actions.push(TransferAsset(blend_id, asset_array, assetCount));\n    }\n\n    actions.push(NoSecurityFuse(blend_id, asset_array));\n\n    try {\n      let tapos = {\n        blocksBehind: 3,\n        expireSeconds: 120,\n      };\n      const result = await user.signTransaction({ actions }, tapos);\n      myGameInstance.SendMessage(\"ConfirmationPanel\", \"ShowSuccess\");\n    } catch (e) {\n      console.log(e);\n      myGameInstance.SendMessage(\n        \"ConfirmationPanel\",\n        \"ShowError\",\n        e.toString()\n      );\n    }\n  },\n```\n\nWhen sending data between Unity and JS, it's important to note that in this example you need to retrieve a string[] value from a memory location and then convert it to a JavaScript string using UTF8 encoding. For example, to achieve this for `contract_names`, you can use the following code snippet:\n\n```js\ncontract_names.push(UTF8ToString(HEAP32[(contractName + i * 4) \u003e\u003e 2]));\n```\n\nAdditionally, since `foreach` doesn't work in this case, you'll need to add parameters for the item count. Once the data is converted, you can perform the necessary operations. Create an array called `actions` and add the required actions to it. Finally, sign the transaction.\n\n**Keep in mind that the only types you can use are arrays ([]), JSON, strings, and you cannot use classes or lists.**\n\n```js\ntry {\n  let tapos = {\n    blocksBehind: 3,\n    expireSeconds: 120,\n  };\n  const result = await user.signTransaction({ actions }, tapos);\n  myGameInstance.SendMessage(\"ConfirmationPanel\", \"ShowSuccess\");\n} catch (e) {\n  console.log(e);\n  myGameInstance.SendMessage(\"ConfirmationPanel\", \"ShowError\", e.toString());\n}\n```\n\nTo add an action, you can follow these steps:\n\n1. Go to the `blockchainTransactions` section.\n2. Locate the desired method.\n3. Ensure that the method returns the required `actions`.\n\nFor example, if you want to add an action, you can navigate to the `blockchainTransactions` section and find the corresponding method. Make sure that the method returns the necessary `actions` object.\n\nPlease ensure that you follow this style when adding your own actions in the `blockchainTransactions` section. Additionally, make use of the global variables `accountName` and `permission` if you need to retrieve the user's wallet name and permission type.\n\n```js\nfunction TransferAsset(asset_array) {\n  return {\n    account: \"atomicassets\",\n    name: \"transfer\",\n    authorization: [\n      {\n        actor: accountName,\n        permission: permission,\n      },\n    ],\n    data: {\n      from: accountName,\n      to: \"blend.nefty\",\n      asset_ids: asset_array,\n      memo: \"deposit\",\n    },\n  };\n}\n```\n\n### Example 3: Retrieving contract tables\n\nThis code example demonstrates how to fetch Blend Whitelist Protection data using the `rpcEndpoint` global variable. The `rpcEndpoint` is used to retrieve contract tables with get_table_rows() method.\n\nTo retrieve the Blend Whitelist Protection data, you can utilize the following code:\n\n```js\nasync function FetchBlendWhitelistProtection(security_id) {\n  let data = await rpcEndpoint.get_table_rows({\n    json: true, // Get the response as json\n    code: \"secure.nefty\", // Contract that we target\n    scope: security_id, // Account that owns the data\n    table: \"whitelists\", // Table name\n    limit: 10, // Maximum number of rows that we want to get\n    reverse: false, // Optional: Get reversed data\n    show_payer: false, // Optional: Show ram payer\n  });\n  return data;\n}\n```\n\nThe `FetchBlendWhitelistProtection` function takes a `security_id` parameter, which represents the account that owns the data. It returns a promise that resolves to the retrieved data.\n\nTo access the retrieved data, you can use the following syntax:\n\n`let data = await FetchBlendWhitelistProtection(security_id);`\n`let rowData = data.rows[rowNumber];`\n\nIn the above code, `data.rows` represents the array of retrieved rows, and `rowNumber` is the index of the specific row you want to access.\n\nTo customize the code based on your specific needs. Here are some parameters that you can modify:\n\n- `code`: Replace `\"secure.nefty\"` with the contract code of your target contract.\n- `scope`: Modify `security_id` according to the usually account or an id.\n- `table`: Change `\"whitelists\"` to the name of the table you want to fetch data from.\n- `limit`: Adjust the number to fetch a specific maximum number of rows.\n- `reverse`: Set `true` if you want the data to be fetched in a reversed order.\n\n### Example 4: Retrieving and Deserializing Data from AtomicAssets\n\nTo retrieve data from AtomicAssets in your project, I recommend referring to the documentation available at [https://aa.neftyblocks.com/docs/#/](https://aa.neftyblocks.com/docs/#/).\n\nIn C#, when you make a JSON call, the first step is to deserialize the response. To achieve this, you need to create a class that represents the structure of the JSON data. You can use a site like [https://app.quicktype.io/](https://app.quicktype.io/) to generate the class based on the retrieved JSON. Set the following settings:\n\n![enter image description here](https://i.ibb.co/pRJZWLr/Screenshot-14.png)\n\nHere's an example of how the output would look if you query this link with the specified request URL: `https://aa.neftyblocks.com/atomicassets/v1/assets?page=1\u0026limit=1\u0026order=desc\u0026sort=asset_id`:\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"contract\": \"atomicassets\",\n      \"asset_id\": \"...\",\n      \"owner\": \"...\",\n      \"is_transferable\": true,\n      \"is_burnable\": true,\n      \"collection\": {\n        \"collection_name\": \"alien.worlds\",\n        \"name\": \"Alien Worlds\",\n        \"img\": \"QmZBpRKm5qigpfDdYgxtcefZ7Cn3GeWHCMBEsk6wYXP4gg\",\n        \"author\": \"federation\",\n        \"allow_notify\": true,\n        \"authorized_accounts\": [\n          \"federation\",\n          \"open.worlds\",\n          \"terra.worlds\",\n          \"m.federation\",\n          \"s.federation\",\n          \"uspts.worlds\",\n          \"awlndratings\",\n          \"nftmt.worlds\"\n        ],\n        \"notify_accounts\": [\n          \"federation\",\n          \"m.federation\"\n        ],\n        \"market_fee\": 0.01,\n        \"created_at_block\": \"70292143\",\n        \"created_at_time\": \"1596576277500\"\n      },\n      ...\n    }\n  ],\n  \"query_time\": 1685447137253\n}\n```\n\nTo use this JSON in Unity with Neftwon.Soft, you need to create a class and paste the parsed JSON. The class would look like this. Make sure that `JsonProperty(jsonName)` is identical to the one in the JSON:\n\n```csharp\nnamespace QuickTyp\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Globalization;\n    using Newtonsoft.Json;\n    using Newtonsoft.Json.Converters;\n\n    public partial class Example\n    {\n        [JsonProperty(\"success\")]\n        public bool Success { get; set; }\n\n        [JsonProperty(\"data\")]\n        public List\u003cDatum\u003e Data { get; set; }\n\n        [JsonProperty(\"query_time\")]\n        public long QueryTime { get; set; }\n    }\n\n    public partial class Datum\n    {\n        [JsonProperty(\"contract\")]\n        public string Contract { get; set; }\n\n        [JsonProperty(\"asset_id\")]\n        public string AssetId { get; set; }\n\n        [JsonProperty(\"owner\")]\n        public string Owner { get; set; }\n\n        [JsonProperty(\"is_transferable\")]\n        public bool IsTransferable { get; set; }\n\n        [JsonProperty(\"is_burnable\")]\n        public bool IsBurnable { get; set; }\n\n        [JsonProperty(\"collection\")]\n        public Collection Collection { get; set; }\n\n        [JsonProperty(\"schema\")]\n        public Schema Schema { get; set; }\n\n        [JsonProperty(\"template\")]\n        public Template Template { get; set;\n\t }\n\t ...\n}\n```\n\nThis class can be used to fetch and deserialize the JSON response from AtomicAssets. This response is structured in a way that allows for easy access to the required data.\nHere's an example of code that uses the `IFetcher` interface within the `Assets/Scripts/Fetcher` folder:\n\n```csharp\n// To get JSON response you would use\nvar exampleUrl = \"https://aa.neftyblocks.com/atomicassets/v1/assets?page=1\u0026limit=1\u0026order=desc\u0026sort=asset_id\";\nvar deserializedJsonResult = await GetDeserializedData\u003cExample\u003e(exampleUrl);\nvar assetID = deserializedJsonResult.Data[0].AssetId;\n```\n\nIn this code snippet, `GetDeserializedData\u003cExample\u003e(exampleUrl)` is a function that fetches the JSON response from the API call, and then deserializes it. The generic `Example` parameter indicates the type to which the JSON should be deserialized. After deserialization, you can access the desired data using the `deserializedJsonResult` object. For example, `deserializedJsonResult.Data` gives you access to the retrieved data, and `deserializedJsonResult.Data[0].AssetId` retrieves the `AssetId` property of the first item in the data array.\n\n### Example 5: Sending arguments from JS to Unity\n\nThis example provides instructions on how to send JavaScript (JS) code to Unity.\n\n**Step 1: Initialize Unity Canvas Variable**\n\nTo begin, you need to initialize the Unity Canvas variable in the `WebGL-Build/index.html` file. Add the following code snippet to initialize the `myGameInstance` variable with the Unity instance:\n\n```html\n\u003c!-- WebGL-Build/index.html --\u003e\n\n\u003cscript\u003e\n  var script = document.createElement(\"script\");\n  script.src = loaderUrl;\n  var myGameInstance = null;\n\n  script.onload = () =\u003e {\n    createUnityInstance(canvas, config, (progress) =\u003e {\n      progressBarFull.style.width = 100 * progress + \"%\";\n    })\n      .then((unityInstance) =\u003e {\n        loadingBar.style.display = \"none\";\n        myGameInstance = unityInstance;\n\n        // Additional initialization code if needed\n\n        fullscreenButton.onclick = () =\u003e {\n          unityInstance.SetFullscreen(1);\n        };\n      })\n      .catch((message) =\u003e {\n        alert(message);\n      });\n  };\n\u003c/script\u003e\n```\n\nMake sure to replace `loaderUrl` with the appropriate URL for your Unity build.\n\n**Step 2: Sending Messages from JS to Unity**\n\nOnce the Unity Canvas variable is initialized, you can use the `myGameInstance.SendMessage()` function to send messages from JS to Unity. The following code snippet demonstrates how to use this function:\n\n```js\n// JavaScript code\nmyGameInstance.SendMessage(\"LoginEnvironment\", \"LoggedIn\", window.accountName);\n```\n\nIn the above example, the message is sent to the Unity object named \"LoginEnvironment\". The method \"LoggedIn\" is called, and `window.accountName` is passed as a variable.\n\n**Step 3: Handling the Message in Unity (C#)**\n\nTo handle the message sent from JS in Unity, you need to define a corresponding method in your C# script. The following code snippet shows an example of how to handle the \"LoggedIn\" message:\n\n```csharp\n// C# code\npublic void LoggedIn(string walletName)\n{\n    loginPanelUI.SetActive(false);\n    pluginController.SetWalletName(walletName);\n    uIManager.EnableInventoryMainMenuUI();\n    walletText.text = walletName;\n}\n```\n\nIn the above code, the \"LoggedIn\" method is defined, which takes a `walletName` parameter. You can customize this method according to your requirements. In this example, the code sets the login panel UI to inactive, sets the wallet name using `pluginController.SetWalletName()`, enables the inventory main menu UI using `uIManager.EnableInventoryMainMenuUI()`, and updates the wallet text.\n\nWith these steps, you can send JavaScript code to Unity and handle the messages in your C# scripts. Customize the code snippets based on your project's specific needs.\n\n## 🚀 Deployment\n\nTo enable continuous integration, the plugin provides a pre-configured GitHub Actions workflow in the `.github` folder. Inside this folder, you'll find a YAML file template that automates the testing, building, and deployment of your Unity game for WebGL. The workflow consists of multiple jobs, including running tests, building the game, deploying to GitHub Pages, and deploying to Vercel. This workflow streamlines the integration process and ensures that your game is tested, built, and deployed efficiently.\n\nIf you want it to generate in Vercel:\n\n1.  Retrieve your [Vercel Access Token](https://vercel.com/guides/how-do-i-use-a-vercel-api-access-token)\n2.  Install the [Vercel CLI](https://vercel.com/cli) and run `vercel login`\n3.  Inside your folder, run `vercel link`to create a new Vercel project\n4.  Inside the generated `.vercel`folder, save the `projectId`and `orgId`from the `project.json`\n5.  Inside GitHub, add `VERCEL_TOKEN`, `VERCEL_ORG_ID`, and `VERCEL_PROJECT_ID`as [secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)\n\n### Important note\n\nEnsure that the project is built to see changes in the Vercel environment. Refer to Step 4 of the **Installation** for instructions on how to accomplish this.\n\n## 🧪 Running the tests\n\nTo run the tests for this project, follow the steps below:\n\n1.  Navigate to the `Assets/Tests/EditModeTests/` directory.\n2.  Right-click on the folder and select \"Create\" \u003e \"Testing\" \u003e \"C# Test script\" to create a new file.\n3.  I recommend separating the `[Setup]` and `[Teardown]` sections to improve code cleanliness.\n4.  Example of a test case located in the `BlendControllerTest` script:\n\nTo ensure clarity and code isolation, follow the Act/Assert/Arrange pattern for your tests. Additionally, use `Substitute.For\u003cClassName\u003e()` from the NSubstitute framework to create mock objects. This helps in isolating the code being tested.\n\n```csharp\n private BlendController blendController;\n    private ISendTransactionJS sendTransactionJS;\n    private CraftAssetPopupController craftAssetPopupController;\n    private BlendProtectionController blendProtectionController;\n\n    [SetUp]\n    public void SetUp()\n    {\n        var blendControllerObject = new GameObject();\n        blendController = blendControllerObject.AddComponent\u003cBlendController\u003e();\n\n        // Mocking\n        sendTransactionJS = Substitute.For\u003cISendTransactionJS\u003e();\n        craftAssetPopupController = Substitute.For\u003cCraftAssetPopupController\u003e();\n        blendProtectionController = Substitute.For\u003cBlendProtectionController\u003e();\n        blendController.sendTransactionJS = sendTransactionJS;\n        blendController.blendProtectionController = blendProtectionController;\n        blendController.craftAssetPopupController = craftAssetPopupController;\n    }\n\n    [TearDown]\n    public void TearDown()\n    {\n        Object.DestroyImmediate(blendController.gameObject);\n    }\n\n    [Test]\n    public void CanBlend_ReturnsTrue_IfPopulatedWithSelectedAssetIds()\n    {\n        //Arrange\n        blendController.requirementPanel = CreatePopulatedRequirementPanel(10);\n\n        // Act\n        bool canBlend = blendController.CanBlend();\n        // Assert\n        Assert.IsTrue(canBlend);\n    }\n```\n\n## How to run code coverage reports\n\n- Open the test runner by navigating to \"Window\" \u003e \"Analysis\" \u003e \"Code Coverage\".\n- In the test runner, click on \"Generate Report\" to execute the tests and generate a report.\n- The test runner will display the results of the tests, including any failures or errors.\n- It should open a folder with the report and by clicking index.html you can analyze the test results to ensure that all tests pass successfully and how much code is covered.\n\nBy following these steps, you will be able to run the tests for the project and generate a report using the Unity test runner.\n\n## How to Add a Plugin to an Existing Project\n\nHere's an improved version for better readability on GitHub:\n\nTo add a plugin to your game that you've built, follow these steps:\n\n1. Launch the plugin and navigate to the Assets folder.\n2. Select all the folders and right-click, then choose \"Export package...\".\n3. In the export window, select \"All\" and click \"Export\". Save the file in your desired folder.\n4. Launch your own project and locate the files of your project.\n5. Drag and drop the exported file into your project's files.\n6. Select all the files and click \"Import\" to import them into your project.\n7. Make sure to go to \"File\" \u003e \"Build Settings\".\n8. From the folder, locate the file named \"Scenes/PluginScene\" and drag it into the \"Scenes in Build\" section.\n9. Now, one way to activate the plugin is by creating a script and attaching it to a button.\n10. Inside the button, add the following method:\n\n```csharp\npublic void SwitchScene()\n{\n    SceneManager.LoadScene(\"PluginScene\");\n}\n```\n\n11. After that, when the button is clicked, the scene will change to the plugin scene.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneftyblocks%2Fnefty-blends-unity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneftyblocks%2Fnefty-blends-unity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneftyblocks%2Fnefty-blends-unity/lists"}