diff --git a/dictionary.txt b/dictionary.txt index 701111d..d5cef37 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -5,6 +5,7 @@ A1 A2 ABI +ABIs Addons addons addon @@ -18,7 +19,10 @@ analytics async APIs AppStore +Appkit +AppKit auth +abi-to-csharp-converter AUTH backend BalanceOf @@ -31,6 +35,7 @@ blockchain Blockchain blockchains Blockchains +blockchain-events BSC BuyItemWebGL BuyItemWebWallet @@ -55,6 +60,8 @@ chainID ChainId chainsafe ChainSafe +Chainsafe +Chainsafes ChainSafe's Chainstack ChainID's @@ -63,6 +70,7 @@ cheatsheet CLI Cloudflare config +Config contract-abi-to-json-format contractAbi convert-wei-to-eth-and-eth-to-wei @@ -77,7 +85,9 @@ DApp devs dev devsetup +dropdown ECDSA +Erc20Contract erc20NameOf EVM-compatible EVM-compatible @@ -128,9 +138,11 @@ goerli Goerli goerli's GasLimit +Gamers getter gamers gameplay +GameObject GitHub github Goerli's @@ -175,7 +187,9 @@ mainnets mainnetgoerli metamask MetaMask +Metamask Multicall +MultiCall multicall minter-evm minting-nft @@ -188,18 +202,22 @@ NewtonSoft newtonsoft non-EVM NFT +NFTS NFTPixels nft-textures NFT's NFTPixels NFTs +nfts nodeJS NodeJS npm onboarding OpenSea OPM +openUPM openupm-cli +OnDestroy OpenUPM prebuilt preconfigured @@ -210,12 +228,16 @@ Rinkeby rpc RPC RPCs +Reown +reown SampleLoginMetamask +SampleMain scalable scrollable SampleScene scriptable Scriptable +ScriptableObject SDK SDK. SDK's @@ -224,6 +246,7 @@ send-contract-through-webgl send-transaction-through-webgl sepolia Sepolia +Sepolia's sha3 SHA3 sign-through-webgl @@ -261,6 +284,7 @@ TypeError UI Unity3D uncomment +unsubscription Uncomment UnityEnvironment UNPKG @@ -324,12 +348,16 @@ Web3AuthSigner Web3Builder WebGLWallet WebPageWallet +WebSocket +WebSockets WebAssembly xdai XDai YourGame Zenject +zkDungeon localhost +Localhost localhost:8000 https Brotli diff --git a/docs/1_chainsafe-gaming.md b/docs/1_chainsafe-gaming.md index a3c14a5..45d01d1 100644 --- a/docs/1_chainsafe-gaming.md +++ b/docs/1_chainsafe-gaming.md @@ -34,7 +34,20 @@ Out-of-the-box, Web3.unity comes with Unity sample scripts, scenes, prefabs & to ## Ready To Get Started? -#### Current SDK Builds (v2.x) +#### Current SDK Builds (v3.x) + +In the latest 3.0 we've significantly reduced the effort for developers to interact with the blockchain. Once you have the core package installed you can just drag and drop the Web3Unity prefab to the scene: + +```csharp +public class ExampleClass : MonoBehaviour +{ + public async void Start() + { + await Web3Unity.Instance.Initialize(false); + await Web3Unity.Web3.Erc20.BalanceOf("0xd25b827D92b0fd656A1c829933e9b0b836d5C3e2"); + } +} +``` [Click here](https://docs.gaming.chainsafe.io/current/getting-started) to open documentation for the latest version of web3.unity. diff --git a/docs/nft_marketplace/2_tutorial.md b/docs/nft_marketplace/2_tutorial.md index e5d87e5..169d0f8 100644 --- a/docs/nft_marketplace/2_tutorial.md +++ b/docs/nft_marketplace/2_tutorial.md @@ -71,9 +71,152 @@ Once you have created a marketplace, its time to list some NFTs for sale in the ![](./assets/list_nft.gif) - -## 4. Launch Your Marketplace - -Once you have listed NFTs for your marketplace, you can access your marketplace items via RESTful set of APIs provided by the ChainSafe. +## 4. Use marketplace inside of your Unity game +Add the Chainsafe marketplace package as a git package: +`https://github.com/ChainSafe/web3.unity.git?path=/Packages/io.chainsafe.web3-unity.marketplace` +Add Marketplace Service Adapter to the Web3Unity prefab + +![](./assets/marketplace_sample.png) + +Fill out the necessary details + + +![](./assets/marketplace_overview.png) + + +- Marketplace ID: Labeled as ID on the page of your marketplace. +- Marketplace contract address: Labeled as Address on the page of your marketplace. +- Project ID override: Override this value if you want to use a project ID that is different from the one that you have in your Chainsafe SDK settings. +- Marketplace ABI override: Override this if you have created a custom version of our marketplace smart contract. +- Endpoint override: Override this if you are hosting marketplace somewhere else other than on the Chainsafes dashboard. + +Once you fill out all the details you can list the items from the marketplace by simply calling + +```csharp +var marketplacePage = await Web3Unity.Web3.Marketplace().LoadPage(); +``` +This will retrieve you a marketplace page, and not all the items that you have listed, because marketplace supports pagination, so you can add pagination support on your Unity client as well. +The basic sample can be found in the Samples section of the Marketplace package, but for the sake of simplicity I'll add the listing code snippet in here. +```csharp +namespace ChainSafe.Gaming.Marketplace.Samples +{ + public class MarketplaceSample : MonoBehaviour + { + [SerializeField] private Transform parentForItems; + [SerializeField] private UI_MarketplaceItem marketplaceItem; + [SerializeField] private Button nextPageButton; + + private MarketplacePage _currentPage; + private async void Start() + { + //Always make sure to initialize the Web3Unity instance first. + await Web3Unity.Instance.Initialize(false); + try + { + LoadingOverlay.ShowLoadingOverlay(); + //This gets all items from the marketplace + //LoadPage has a lot of parameters that you can fill out in order to filter out the results. + _currentPage = await Web3Unity.Web3.Marketplace().LoadPage(); + + nextPageButton.interactable = !string.IsNullOrEmpty(_currentPage.Cursor); + + await DisplayItems(); + } + catch (Exception e) + { + Debug.LogError("Caught an exception whilst loading the marketplace page " + e.Message); + } + finally + { + LoadingOverlay.HideLoadingOverlay(); + } + } + + private async Task DisplayItems() + { + for (int i = parentForItems.childCount - 1; i >= 0; i--) + { + Destroy(parentForItems.GetChild(i).gameObject); + } + //_currentPage.Items holds the reference to all the items fetched from the marketplace + foreach (var pageItem in _currentPage.Items) + { + var item = Instantiate(marketplaceItem, parentForItems); + await item.Initialize(pageItem); + } + } + } +} + + + //Monobehaviour that handles the display of the marketplace items. + public class UI_MarketplaceItem : MonoBehaviour + { + [SerializeField] private Image marketplaceItemImage; + [SerializeField] private TMP_Text type, itemId, itemPrice, itemStatus; + [SerializeField] private Button button; + + private MarketplaceItem _marketplaceItemModel; + + private static Dictionary _spritesDict = new(); + + public async Task Initialize(MarketplaceItem model) + { + _marketplaceItemModel = model; + button.interactable = model.Status == MarketplaceItemStatus.Listed; + itemStatus.text = model.Status == MarketplaceItemStatus.Listed ? "Purchase" : model.Status.ToString(); + marketplaceItemImage.sprite = await GetSprite(model); + type.text = model.Token.Type; + itemId.text = "ID " + model.Token.Id; + itemPrice.text = + ((decimal)BigInteger.Parse(model.Price) / (decimal)BigInteger.Pow(10, 18)).ToString("0.############", + CultureInfo.InvariantCulture) + Web3Unity.Web3.ChainConfig.Symbol; + button.onClick.AddListener(Purchase); + } + + private async Task GetSprite(MarketplaceItem model) + { + Sprite sprite = null; + string imageUrl = (string)model.Token.Metadata["image"]; + //Caching data for faster retreival of the sprites. + if (_spritesDict.TryGetValue(imageUrl, out sprite)) return sprite; + + var unityWebRequest = UnityWebRequestTexture.GetTexture(imageUrl); + await unityWebRequest.SendWebRequest(); + if (unityWebRequest.error != null) + { + Debug.LogError("There was an error getting the texture " + unityWebRequest.error); + return null; + } + + var myTexture = ((DownloadHandlerTexture)unityWebRequest.downloadHandler).texture; + + sprite = Sprite.Create(myTexture, new Rect(0, 0, myTexture.width, myTexture.height), Vector2.one * 0.5f); + + return sprite; + } + + private async void Purchase() + { + try + { + await Web3Unity.Web3.Marketplace().Purchase(_marketplaceItemModel.Id, _marketplaceItemModel.Price); + //After the purchase is sucsessfull, just make the button unresponsive and set the button indicator to Sold + button.interactable = false; + itemStatus.text = "Sold"; + } + catch (ServiceNotBoundWeb3Exception _) + { + Debug.LogError("You wanted to purchase an item and you don't have a wallet. Please connect the wallet to make a purchase"); + Web3Unity.ConnectModal.Open(); + } + } + } + +``` + +## 5. Use marketplace with the Rest API + +If you prefer to access your items without our official Marketplace plugin, once you have listed NFTs for your marketplace, you can access your marketplace items via RESTful set of APIs provided by the ChainSafe. Head over to the [Marketplace API Specification](./../marketplace-api/docs/marketplaceapi.mdx) to know more about how to interact with the marketplace items. diff --git a/docs/nft_marketplace/assets/marketplace_overview.png b/docs/nft_marketplace/assets/marketplace_overview.png new file mode 100644 index 0000000..2f9c38e Binary files /dev/null and b/docs/nft_marketplace/assets/marketplace_overview.png differ diff --git a/docs/nft_marketplace/assets/marketplace_sample.png b/docs/nft_marketplace/assets/marketplace_sample.png new file mode 100644 index 0000000..135a16a Binary files /dev/null and b/docs/nft_marketplace/assets/marketplace_sample.png differ diff --git a/docs/v2.6/15_marketplace.md b/docs/v2.6/15_marketplace.md deleted file mode 100644 index 439d949..0000000 --- a/docs/v2.6/15_marketplace.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -slug: /current/marketplace -sidebar_position: 15 -sidebar_label: Marketplace ---- - - -# Marketplace - -:::info - -This page will walk you through our marketplace feature. - -::: - -## What is the ChainSafe marketplace? -ChainSafe's marketplace is an NFT trading hub where you can create collections of NFTs and list them in different marketplaces. You can then display these marketplaces and interact with them in game. The marketplace dashboard can be accessed [here](https://dashboard.gaming.chainsafe.io/marketplaces). You can find a variety of services here to compliment your marketplace, from collections to minting NFTs. - -1. You can import our Marketplace sample scene by navigating to Window → Package Manager. -2. Add a new package by name by pressing + and adding via git url and entering `https://github.com/ChainSafe/web3.unity.git?path=/Packages/io.chainsafe.web3-unity.marketplace` -3. Once the package is installed, click on the Samples tab. Import the samples. -4. Once imported, you can find the scene by navigating to Samples → Web3.unity SDK → 2.6 → Web3.Unity Samples → Scenes → SampleLogin - Marketplace. -5. Click on the Login Logic - Ramp object and in the inspector, modify the Scene To Load to your preferred scene. -6. Add the Marketplace scene and your scene to the build settings, and you’re done. - -## How do I access the marketplace? -The marketplace dashboard can be accessed [here](https://dashboard.gaming.chainsafe.io/marketplaces) -The NFT dashboard can be accessed [here](https://dashboard.gaming.chainsafe.io/nfts) - -## Can I use this within my unity project? -You certainly can! With our new marketplace package you can call marketplace data, list and even purchase NFTs from other marketplaces. - -## What about metadata? -We've included a function to upload files automatically to ChainSafe's storage which will also pin to IPFS. This is automatically done in the creation calls found in the marketplace package. We've also included this in a more granular fashion in the IPFS calls section of the sample main scene should you want to have alternate metadata for your NFTs. \ No newline at end of file diff --git a/docs/v2.6/18_faq.md b/docs/v2.6/18_faq.md index 2f0e46d..9213f0a 100644 --- a/docs/v2.6/18_faq.md +++ b/docs/v2.6/18_faq.md @@ -132,3 +132,11 @@ You need to add the web3 component into your react build manually. To do so: \ \ \ \ ``` This should solve your issue. Happy coding! + +### I'm having `IndexOutOfRangeException` exception thrown when building to WebGL + +``` +IndexOutOfRangeException: Index was outside the bounds of the array. +``` + +When building to WebGL you could run into this issue on some Unity versions. To fix this, simply open your project's _Player Settings_ then navigate to _Resolution and Presentation_ and pick **Web3.Unity** under _WebGL Template_. Even if it was already selected your project should be able to build to WebGL now. diff --git a/docs/v2.6/19_abi-to-csharp-converter.md b/docs/v2.6/19_abi-to-csharp-converter.md new file mode 100644 index 0000000..5aef113 --- /dev/null +++ b/docs/v2.6/19_abi-to-csharp-converter.md @@ -0,0 +1,52 @@ +--- +slug: /current/abi-to-csharp-converter +sidebar_position: 19 +sidebar_label: Contract ABI To C# Generator +--- + +# Contract ABI To C# Generator +In version 3.0, we've made it super easy for you to communicate with the blockchain by introducing the ABI to C# converter. Besides encapsulating all of your contract ABI into more user-friendly, statically typed methods, this utility also allows you to easily subscribe to and unsubscribe from the events happening on the blockchain. + +You can access it by clicking on the top menu: Chainsafe SDK > Contract ABI To C# Generator. + +![Contract ABI TO C# converter](assets/abi-csharp-contract/abi-csharp-overview.png) + +Once there, you need to fill out the name of your contract and the folder where you want the C# contract to be generated. + + +![Contract ABI TO C# converter](assets/abi-csharp-contract/abi-csharp-filled.png) + +If the data you provided is correct, you can click on Generate. After a few seconds, and once Unity reloads the domain, you should see a newly created C# class inside of your project. + +Now, to actually interact with both the events and methods from the contract, the only remaining information needed is the contract address. + +Here is a sample script for the Erc20Contract that we've generated in the previous images: + +```csharp +public class CustomContractSample : MonoBehaviour +{ + [SerializeField] private string contractAddress; + [SerializeField] private string balanceOfAddress; + + Erc20Contract _erc20Contract; + + public async void Start() + { + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); + + _erc20Contract = await Web3Unity.Instance.BuildContract(contractAddress); + //Calling any read method from the smart contract: + var balanceOf = await _erc20Contract.BalanceOf(balanceOfAddress); + } + + public async void OnDestroy() + { + _erc20.OnTransfer -= Erc20Transfer; + await _erc20Contract.DisposeAsync(); + } + +} +``` + +Since we subscribe to blockchain events from the ABI during the contract building process behind the scenes, we need to manually dispose of the contract in a method like OnDestroy, which will handle unsubscribing from those events. diff --git a/docs/v2.6/1_getting-started.md b/docs/v2.6/1_getting-started.md index 7b0dbae..0447721 100644 --- a/docs/v2.6/1_getting-started.md +++ b/docs/v2.6/1_getting-started.md @@ -25,6 +25,9 @@ Our packages are modular so your project wont bloat out with SDK files and you c Core SDK: `https://github.com/ChainSafe/web3.unity.git?path=/Packages/io.chainsafe.web3-unity` +If you prefer to download packages trough openUPM you can do it trough the following link: +`https://openupm.com/packages/io.chainsafe.web3-unity/?subPage=readme` + Please note that each package has samples that can be installed, these samples are built to give you a working example on the packages calls. You will also need the CORE SDK samples package if you want to work with the sample scripts seen [here](/current/sample-scripts) ![](assets/getting-started/import-samples.png) @@ -37,12 +40,24 @@ Go to window → package manager → select the web3.unity SDK package and press ### Set Project ID -As the package is installed, you'll be prompted with the ChainSafe server settings. First you have to setup your Project ID. You can create one [here](https://dashboard.gaming.chainsafe.io/) or you can click on the "Need To Register?" button in the server settings. +As the package is installed, you'll be prompted with the ChainSafe server settings. First you have to setup your Project ID. You can create one [here](https://dashboard.gaming.chainsafe.io/) or you can click on the "Get a Project ID" button in the server settings. ![](assets/getting-started/project-settings.png) -After you've completed the registration process, copy your Project ID into the project settings window. You should see a message in the console saying your project id is valid. Select the chain you would like to use and the rest of the fields will auto populate. If you would like to set up your own RPC node, visit [this page](https://docs.gaming.chainsafe.io/current/setting-up-an-rpc-node). +After you've completed the registration process, copy your Project ID into the project settings window. You should see a message in the console saying your project id is valid. +Next up, you need to set up the list of chains you want to interact with inside of your project: + +![](assets/getting-started/chain-settings.png) + +You need a minimum of 1 chain for the SDK to work normally. + +Small note: All of our samples are made on the Ethereum Sepolia network. If you run the samples whilst you are on another chain, you will get an exception. If you need to refer to the ChainSafe server settings area again, you can find it on the top navigation bar. Simply select it and press server settings to view the menu. -![](assets/getting-started/project-settings-menu.png) \ No newline at end of file +![](assets/getting-started/project-settings-menu.png) + +### Drag and drop Web3Unity Prefab into your scene. +You can find the Web3Unity Prefab by typing Web3Unity in the project search bar. From the Search: Choose either 'All' or 'In Packages' + +![](assets/getting-started/web3unity-prefab.png) \ No newline at end of file diff --git a/docs/v2.6/20_chain-switching.md b/docs/v2.6/20_chain-switching.md new file mode 100644 index 0000000..906edba --- /dev/null +++ b/docs/v2.6/20_chain-switching.md @@ -0,0 +1,41 @@ +--- +slug: /current/chain-switching +sidebar_position: 20 +sidebar_label: Chain Switching +--- + +# Chain Switching +In version 3.0, we've added the most requested feature from the community—chain switching. + +Chain switching allows you to seamlessly switch between chains if you need to interact with smart contracts that are deployed on a different chain. +![](assets/chain-switching/chain-settings.png) +In the Chain Settings inside the ChainSafe SDK > Project Settings, you can add as many chains as you'd like. + +The first chain in the list will always be the initial one that Web3Unity connects to. + +The API for switching between chains is simple—just call `await Web3Unity.Web3.SwitchChain(newChainId);`. A more detailed example follows: + +```csharp +public class ChainSwitchingSample : MonoBehaviour +{ + [SerializeField] private string newChainId; + [SerializeField] private string newChainContractAddress; + [SerializeField] private string newChainContractAbi; + + async void Start() + { + //Make sure web3 instance is initialized + var currentChainId = Web3Unity.Web3.Chains.Current.ChainId; + await Web3Unity.Web3.SwitchChain(newChainId); + //For the sake of simplicity, we're demonstrating the 'old-fashioned' way of building contracts. + var contract = await Web3Unity.Web3.ContractBuilder.Build(newChainContractAbi, newChainContractAddress); + //Use the return value however you want. You can always call the contract.Call method even if you don't have the wallet bound to the web3 instance. + var returnValue = await contract.Call("exampleMethod"); + //It's recommended to return back to the old chain as soon as you finish interaction with contracts on the other chains. + await Web3Unity.Web3.SwitchChain(currentChainId); + } + + +} + +``` \ No newline at end of file diff --git a/docs/v2.6/20_mud.md b/docs/v2.6/20_mud.md new file mode 100644 index 0000000..1b4a8a9 --- /dev/null +++ b/docs/v2.6/20_mud.md @@ -0,0 +1,142 @@ +--- +slug: /current/mud +sidebar_position: 20 +sidebar_label: MUD Autonomous Worlds +--- + +# Build Autonomous Worlds with MUD + +## Introduction + +MUD is a framework for ambitious on-chain applications, allowing you to build autonomous worlds that are infinitely +extendable by default. These worlds come with access control, upgradability, hooks, plugins, and a suite of excellent +developer tools. MUD evolved from experiences building cutting-edge on-chain games like Dark Forest and zkDungeon. With +our MUD integration, you can now easily create truly decentralized game applications within Unity! + +_If you're not familiar with MUD and the concept of autonomous worlds, please refer to the [MUD documentation](https://mud.dev/introduction) first._ + +## Building a MUD Application in Unity + +Before you can start developing your Unity MUD application, you should either deploy or run your MUD world locally. A +MUD world is essentially a set of smart contracts with one main contract called 'World'. Please follow the [Hello World +Tutorial](https://mud.dev/quickstart) from the original MUD documentation to get started. + +You can find examples of interacting with the MUD world in the Samples of our UPM package, but we'll cover the most +important parts in this tutorial. + +### Configuring the Web3 Client + +Once you have a tutorial project up and running locally on your machine, you can connect your Unity application to your +MUD world. To do this, you need to configure your Web3 client to communicate with the MUD world: + +```csharp +public MudConfigAsset mudConfig; + +private Web3 web3; + +async void Awake() +{ + web3 = await new Web3Builder( + ProjectConfigUtilities.Load(), // project config + ProjectConfigUtilities.BuildLocalhostConfig()) // chain config + .Configure(services => + { + // ... + + services.UseMud(mudConfig); // enable MUD + }) + .LaunchAsync(); +} +``` + +The MUD module must be configured first in order to be used. You can provide any implementation of `IMudConfig`, but +there is a handy ScriptableObject class that you can use inside Unity called `MudConfigAsset`. + +Notice that we're providing a second configuration to the `Web3Builder`. This instructs `Web3Builder` to use **Localhost** +for our **Chain Configuration**, as we're currently running our MUD world locally using Anvil. + +You should also configure your Web3 client to use one of the accounts from your locally running chain if you plan to +execute any transactions. Here’s how you can do it: + +```csharp +web3 = await new Web3Builder(/* ... */) + .Configure(services => + { + // ... + + // Initializes wallet as the first account of the locally running Ethereum Node (Anvil). + services.Debug().UseJsonRpcWallet(new JsonRpcWalletConfig { AccountIndex = 0 }); + + // ... + }) + .LaunchAsync(); +``` + +### Building the MUD World Client + +Once you have a Web3 client built, you can create a MUD world client with `await web3.Mud().BuildWorld()`. + +_At the moment, the `BuildWorld()` method requires a configuration for your MUD world that you need to fill in manually. +This will change in the future once we introduce strongly-typed code generation for your worlds, similar to what we have +for smart contracts._ + +```csharp +world = await web3.Mud().BuildWorld(new MudWorldConfig +{ + ContractAddress = worldContractAddress, + ContractAbi = worldContractAbi.text, + DefaultNamespace = "app", + TableSchemas = new List + { + new() + { + Namespace = "app", + TableName = "Counter", + Columns = new List> + { + new("value", "uint32"), + }, + KeyColumns = new string[0], // empty key schema - singleton table (one record only) + }, + }, +}); +``` + +### Interacting with Tables + +* You can access any table by calling `world.GetTable(tableName)`. +* You can query table records with `await table.Query(query)`. +* To query all the records from the table, use `MudQuery.All` as the query. +* You can subscribe to table update events using the table object: `table.RecordUpdated += OnCounterRecordUpdated`. + +```csharp +var table = world.GetTable("Counter"); + +// Query counter value +var allRecords = await table.Query(MudQuery.All); // Query all records of the Counter table +var singleRecord = allRecords.Single(); // Get single record +var counterValue = (BigInteger)singleRecord[0]; // Get value of the first column +Debug.Log($"Counter value on load: {counterValue}"); + +// Subscribe to table updates. +table.RecordUpdated += OnCounterRecordUpdated; +``` + +_The way you interact with the table is not perfect and is still a work in progress. We plan to introduce strongly-typed +code generation for tables as well._ + +### Invoking MUD System Functions + +All the logic for the MUD world is located in smart contracts called Systems. You can invoke functions provided by a +System of your MUD world easily using the SDK: + +```csharp +await world.GetSystems().Send("increment"); +``` + +The object provided to you by `GetSystems` has the interface of a smart contract client, meaning you can use it in the +same way you would with a smart contract. Here’s how to call a read-only function: + +```csharp +var playersOnlineCount = await world.GetSystems().Call("getPlayersOnline"); +``` \ No newline at end of file diff --git a/docs/v2.6/21_blockchain-events.md b/docs/v2.6/21_blockchain-events.md new file mode 100644 index 0000000..3e02e67 --- /dev/null +++ b/docs/v2.6/21_blockchain-events.md @@ -0,0 +1,112 @@ +--- +slug: /current/blockchain-events +sidebar_position: 21 +sidebar_label: Listening to Blockchain Events +--- +Here’s the corrected version of your content with improved grammar: + +--- + +# Listening to Blockchain Events +Often, you will want to react to certain events happening on the blockchain. For example, you might want to know when a transfer of funds occurs on a specific smart contract. + +## Prerequisite +Fill in the WebSocket URL for the chains in the ChainSafe SDK > Project Settings. + +To subscribe to the events happening on the blockchain, you need to add the Events Service Adapter to your Web3Unity Prefab. +There, you will find a serialized field called the polling interval. For platforms other than WebGL, any changes made to that number won't take effect, as for WebGL, we use event polling (essentially pinging the RPC every `pollingInterval` seconds to check for new events from a specific address), due to the limitations of the WebGL platform. If you are not building for WebGL (this includes the Editor), you'll use the WebSocket URL provided in your chain configuration. + +:::info +For public WebSockets (like Sepolia's public WebSockets, for example), it can take up to a minute to establish a proper WebSocket connection. If you exit play mode before a minute has passed, you might encounter exceptions indicating that subscription/unsubscription has failed. +::: + +## Subscribing to Events +There are two ways to subscribe to events: either subscribe via generated contracts or do it manually. + +If you are using the generated contracts from our Contract ABI <-> C# Generator, you can subscribe to the events of that smart contract, just like you're used to in C#. + +```csharp +public class CustomContractSample : MonoBehaviour +{ + [SerializeField] private string contractAddress; + + Erc20Contract _erc20Contract; + + public async void Start() + { + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); + + _erc20Contract = await Web3Unity.Instance.BuildContract(contractAddress); + + _erc20.OnTransfer += Erc20Transfer; + } + + public async void OnDestroy() + { + _erc20.OnTransfer -= Erc20Transfer; + + //This unsubscribes you from the websockets internally, don't forget to add it. + await _erc20Contract.DisposeAsync(); + } + + private void Erc20Transfer(Erc20Contract.TransferEventDTO obj) + { + Debug.Log("Transfer happened"); + } +} +``` + +However, if you prefer, you can also handle events manually: + +```csharp +// The Approval event in the standard ERC20 contract (and in the ABI) has the following signature: +// event Approval(address indexed owner, address indexed spender, uint256 value) + +// Encapsulate the event name as it's written in the ABI or smart contract in the Event attribute. +[Event("Approval")] +// The class you're creating for the event must implement the IEventDTO interface. +public class ApprovalEventDTO : IEventDTO +{ + /* + All properties should have the Parameter attribute applied to them. + The first argument is the actual type on the smart contract side. + The second argument is the name of the parameter in the smart contract. + The third argument is the order of that parameter in the invocation. + The last argument indicates if the parameter is indexed or not. + */ + + [Parameter("address", "owner", 0, true)] + public virtual string Owner { get; set; } + + [Parameter("address", "spender", 1, true)] + public virtual string Spender { get; set; } + + [Parameter("uint256", "value", 2, false)] + public virtual BigInteger Value { get; set; } +} + + +public class CustomContractSample : MonoBehaviour +{ + [SerializeField] private string contractAddress; + + public async void Start() + { + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); + + Web3Unity.Web3.Events.Subscribe(Erc20Approval, contractAddress); + } + + public void OnDestroy() + { + Web3Unity.Web3.Events.Unsubscribe(Erc20Approval, contractAddress); + } + + private void Erc20Approval(ApprovalEventDTO obj) + { + Debug.Log("Approval happened"); + } +} +``` \ No newline at end of file diff --git a/docs/v2.6/22_service-adapters.md b/docs/v2.6/22_service-adapters.md new file mode 100644 index 0000000..d2b3055 --- /dev/null +++ b/docs/v2.6/22_service-adapters.md @@ -0,0 +1,48 @@ +--- +slug: /current/service-adapters +sidebar_position: 22 +sidebar_label: Service Adapters +--- + +# Service Adapters + +:::info + +This page shows you how to add additional functionality to your project using service adapters. + +::: + +Service Adapters are used to inject additional services to your Web3 instance. You can do this by attaching `ServiceAdapter` scripts to `Web3Unity` in your scene hierarchy. + +We have multiple service adapters available for you to use in the core package: +- [Events](/current/blockchain-events) service adapter +- MultiCall service adapter - Allows you to batch multiple calls into a single call. +- [Gelato](/current/gasless-transactions-using-Gelato) service adapter + +We have additional service adapters available in our additional packages: +- [Ramp](/current/ramp) service adapter +- [Lootboxes](/current/lootboxes) service adapter +- [Marketplace](/marketplace/tutorial#4-use-marketplace-inside-of-your-unity-game) service adapter + +![img.png](assets/service-adapters/service-adapters.png) + +## Implementing your own Service Adapter + +If you would like to implement your own service adapter you can do so by creating a new script that inherits from the MonoBehaviour class `ServiceAdapter` and implementing the `ConfigureServices` method. Here is an example of how you can create your own service adapter: + +```csharp + +public class SampleServiceAdapter : ServiceAdapter, ISampleService +{ + public override Web3Builder ConfigureServices(Web3Builder web3Builder) + { + return web3Builder.Configure(services => + { + services.AddSingleton(this); + }); + } +} + +``` + +In the example above, we have created a new service adapter called `SampleServiceAdapter` that is also an `ISampleService`. We then override the `ConfigureServices` method and add the `ISampleService` to the service collection to be injected during initialization. Service adapters must be present in the scene hierarchy during initialization to be injected into the Web3 instance. They can be attached anywhere in the scene hierarchy, but we recommend attaching them to the `Web3Unity` GameObject. If you would like your services to be injected without a connection present (during initialization) then your service adapter should also implement `ILightweightServiceAdapter` interface. diff --git a/docs/v2.6/2_choose-your-wallet.md b/docs/v2.6/2_choose-your-wallet.md index 706417c..ca41266 100644 --- a/docs/v2.6/2_choose-your-wallet.md +++ b/docs/v2.6/2_choose-your-wallet.md @@ -21,7 +21,7 @@ Players will use wallets to manage their assets and interact with your games. Th Metamask - Wallet Connect + Reown (Wallet Connect) Web3 Auth Hyperplay @@ -30,7 +30,7 @@ Players will use wallets to manage their assets and interact with your games. Th Browser ✓ - ✗ + ✓ ✓ ✗ @@ -71,10 +71,24 @@ Players will use wallets to manage their assets and interact with your games. Th - Metamask - Wallet Connect - Web3 Auth - Hyperplay + Metamask + Reown (Wallet Connect) + Web3 Auth + Hyperplay - \ No newline at end of file + + +# Add Wallets to Your Unity Game + +Adding wallet providers to your games is simpler than ever. Inside the Web3Unity prefab that you've dragged and dropped into your scene, navigate to the Connection Handler script in your inspector and expand the Connection Providers dropdown. + +![](assets/wallets/overview/connection-handler.png) + +If you've only installed our core package, the two available providers will be WalletConnect (which will be renamed to Reown in future versions) and MetaMask. You can add these as providers by clicking the Add Provider button. This will create new configuration file(s) inside your Resources folder. + +To add support for social login (Google, Facebook, X), you need to install the web3auth package. + +If your game is ready to be published on the Hyperplay launcher, you need to install the Hyperplay package. + + diff --git a/docs/v2.6/3_metamask.md b/docs/v2.6/3_metamask.md index e73b615..195dc85 100644 --- a/docs/v2.6/3_metamask.md +++ b/docs/v2.6/3_metamask.md @@ -6,28 +6,20 @@ sidebar_label: Metamask # MetaMask -:::info - -Please note that MetaMask will only work with WebGL builds that are built out locally or published in the browser. You can use wallet connect to login and scan the QR code on your device to connect with MetaMask if needed for desktop builds. - -::: +## What is Metamask? -Here’s how you can include MetaMask in your video games. -1. You can find the scene by navigating to Samples → web3.unity SDK → 2.6 → Web3.Unity Samples → Scenes → SampleLogin - MetaMask. -2. Click on the Login Logic - MetaMask object and in the inspector, modify the Scene To Load to your preferred scene. +MetaMask is a digital wallet and browser extension that allows users to securely interact with EVM-based games. It acts as a bridge between your browser and the EVM chains, making it easy to send, receive, and swap digital assets. -![](assets/wallets/metamask/metamask-login-logic.png) - -3. Add the MetaMask scene and your scene to the build settings, and you’re done. +:::info -![](assets/wallets/metamask/metamask-login-scene.png) +Please note that MetaMask will only work with WebGL builds that are built out locally or published in the browser. You can use Reown to login and scan the QR code on your device to connect with MetaMask if needed for desktop builds. -Simply login with a local or published WebGL build and connect your MetaMask. +::: ## WebGL Builds -MetaMask uses a custom WebGL template to display your game in your browser. Navigate to File → Build Settings → Player Settings. In player settings, set your resolution to the MetaMask WebGL template. +MetaMask uses a custom WebGL template to display your game in your browser. It should be selected by default but if you run into issues you can navigate to File → Build Settings → Player Settings. In player settings, set your resolution to the Web3.Unity template. ![](assets/wallets/metamask/metamask-project-settings.png) -Now you are ready to build your WebGL game. \ No newline at end of file +Now you are ready to build your WebGL game. diff --git a/docs/v2.6/4_reown.md b/docs/v2.6/4_reown.md new file mode 100644 index 0000000..1fc7c71 --- /dev/null +++ b/docs/v2.6/4_reown.md @@ -0,0 +1,33 @@ +--- +slug: /current/reown +sidebar_position: 4 +sidebar_label: Reown (Wallet Connect) +--- + +# Reown (Wallet Connect) + +## What is Reown (Wallet Connect)? + +Reown is an open protocol that allows users to connect their crypto wallets to games through a QR code or deep link. It enables secure interactions between mobile wallets and Web3 games, making it easy to authorize transactions and access blockchain features from any device. + +## Custom Reown (Wallet Connect) Endpoint + +We've already given you some default values for the Reown (Wallet Connect) configuration so if you're fine with using the same endpoint as everyone else just leave it as is. Otherwise head on over to the dashboard at [Reown (Wallet Connect)](https://cloud.walletconnect.com/sign-in) to sign up and get your own details. + +![](assets/wallets/reown/reown-dash.png) + +Once you're in the Reown (Wallet Connect) dashboard area, you can press the button on the top right to create a new project, it will ask you to give the project a name. + +![](assets/wallets/reown/reown-new-project.png) + +Next select Appkit and then Unity. + +![](assets/wallets/reown/reown-app-kit.png) + +Once you've created the project you'll be taken to the settings area. Here you'll find the input details you need. Scroll down to the Information section and there you can grab the project name and the project id. + +![](assets/wallets/reown/reown-project-info.png) + +Just place these into the editor values, press save and you're good to go. + +![](assets/wallets/reown/reown-connect-info.png) diff --git a/docs/v2.6/4_wallet-connect.md b/docs/v2.6/4_wallet-connect.md deleted file mode 100644 index 5fbead0..0000000 --- a/docs/v2.6/4_wallet-connect.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -slug: /current/wallet-connect -sidebar_position: 4 -sidebar_label: Wallet Connect ---- - -# Wallet Connect - -Here’s how you can include Wallet Connect in your video games. - -1. Once imported, you can find the scene by navigating to Samples → web3.unity SDK → 2.6 → Web3.Unity Samples → Scenes → SampleLogin - WalletConnect. -2. Click on the Login Logic - WalletConnect object and in the inspector, modify the Scene To Load to your preferred scene. - -![](assets/wallets/wallet-connect/wallet-connect-login-logic.png) - -3. Add the Wallet Connect scene and your scene to the build settings, and you’re done. - -## Custom Wallet Connect Endpoint - -We've already given you some default values for the wallet connect configuration so if you're fine with using the same endpoint as everyone else just leave it as is. Otherwise head on over to the dashboard at [Wallet Connect](https://cloud.walletconnect.com/sign-in) to sign up and get your own details. - -![](assets/wallets/wallet-connect/wallet-connect-dash.png) - -Once you're in the Wallet Connect dashboard area, you can press the button on the top right to create a new project, it will ask you to give the project a name. - -![](assets/wallets/wallet-connect/wallet-connect-new-project.png) - -Once you've created the project you'll be taken to the settings area. Here you'll find the input details you need, the project name and the project id. - -![](assets/wallets/wallet-connect/wallet-connect-project-id.png) - -Just place these into the editor values, press save and you're good to go. - -![](assets/wallets/wallet-connect/wallet-connect-info.png) \ No newline at end of file diff --git a/docs/v2.6/5_web3auth.md b/docs/v2.6/5_web3auth.md index 51c6eb1..12efdd4 100644 --- a/docs/v2.6/5_web3auth.md +++ b/docs/v2.6/5_web3auth.md @@ -7,27 +7,32 @@ sidebar_label: Web3Auth # Web3Auth ## What is Web3Auth? + Web3Auth is a wallet solution that allows users to connect to the blockchain via social logins. Upon logging in you'll receive a wallet that is fully functional and able to make calls with our SDK. -Here’s how you can include Web3Auth in your video games. +## Populating the Configuration file + +Once you have imported the package, Web3Auth entry will be available in the Connection Handler script in the inspector. Click on Add Provider to generate the Web3Auth configuration file. + +![](assets/wallets/web3auth/web3auth-config.png) + +### Web3Auth Wallet GUI +Before showing you the process on how to add your own Client Id, we just want to introduce you to the new feature we've added in the 3.0.0 and that is Web3Auth Wallet GUI. +We got a lot of requests to make the social logins with web3auth also feel like the regular wallets, where you would also be able to approve and decline transactions, see the latest transactions you've done in this session and also check balances of some of your native tokens and read the balance of the chain that you are on. -1. You can import our Web3Auth sample scene by navigating to Window → Package Manager. -2. Add a new package by name by pressing + and pressing add via git url entering `https://github.com/ChainSafe/web3.unity.git?path=/Packages/io.chainsafe.web3-unity.web3auth` -3. Once the package is installed, click on the Samples tab. Import the samples. +![Web3Auth wallet](assets/wallets/web3auth/web3auth-wallet.png) -![](assets/wallets/web3auth/web3auth-import.png) +#### Web3Auth Wallet GUI configuration -4. Once imported, you can find the scene by navigating to Samples → web3.unity SDK Web3Auth → 2.6 → Web3.Unity Web3Auth Samples → Scenes → SampleLogin - Web3Auth. -5. Click on the Login Logic - Web3Auth object and in the inspector, modify the Scene To Load to your preferred scene. +![Web3Auth wallet](assets/wallets/web3auth/web3authgui-config.png) -![](assets/wallets/web3auth/web3auth-login-logic.png) +In the connection provider settings, you have the Enable Wallet GUI toggle, which, when turned on, will instantiate the wallet GUI once the user is logged in. -6. Add the Web3Auth scene and your scene to the build settings, and you’re done. +In the Wallet GUI Config, you can fine-tune the behavior and appearance of the Wallet GUI by modifying the colors and deciding if you want to auto-confirm transactions. You can also choose to view the transaction hash history in the GUI without requiring the end user to approve every write call to the blockchain. -We hope you enjoy social logins as it offers a unique way to onboard users to the blockchain without actually requiring a wallet. +### Getting Client Id -## Moving to Production -The default settings for Web3Auth are great for testing but once you're ready to move to production you will want to manage your won API key. To get started, visit the [Web3Auth dashboard](https://dashboard.web3auth.io/) and create your account. +In order to properly populate the Client Id and redirect URL go to [Web3Auth dashboard](https://dashboard.web3auth.io/) In the dashboard, click on project navigation column on the left, and click "Create Project". @@ -40,10 +45,3 @@ In the create new project menu, be sure to choose "Plug and Play" for your produ When you create your project, you'll be redirected to the project page. Copy your client ID and open Unity. ![](assets/wallets/web3auth/web3auth-project-page.png) - - -Click on the Login Logic - Web3Auth object and in the inspector, paste in your client ID in the client ID field under the Web3Auth section. - -![](assets/wallets/web3auth/web3auth-login-logic.png) - -Now you are all set to move to production! \ No newline at end of file diff --git a/docs/v2.6/6_hyperplay.md b/docs/v2.6/6_hyperplay.md index 1b2455e..907d535 100644 --- a/docs/v2.6/6_hyperplay.md +++ b/docs/v2.6/6_hyperplay.md @@ -9,21 +9,11 @@ sidebar_label: Hyperplay ![](assets/wallets/hyperplay/hyperplay-title.png) ## What is HyperPlay? -HyperPlay is a wallet solution that runs in a desktop client, it uses web requests to communicate with the wallet with the client and makes connecting to games easy and simple. - -Here’s how you can include Hyperplay in your video games. -1. You can import our Hyperplay sample scene by navigating to Window → Package Manager. -2. Add a new package by name by pressing + and adding via git url and entering `https://github.com/ChainSafe/web3.unity.git?path=/Packages/io.chainsafe.web3-unity.hyperplay` -3. Once the package is installed, click on the Samples tab. Import the samples. -4. Once imported, you can find the scene by navigating to Samples → web3.unity SDK → 2.6 → Web3.Unity Samples → Scenes → SampleLogin - Hyperplay. -5. Click on the Login Logic - Hyperplay object and in the inspector, modify the Scene To Load to your preferred scene. -6. Add the Hyperplay scene and your scene to the build settings, and you’re done. - -![](assets/wallets/hyperplay/hyperplay-login.png) +HyperPlay is a wallet solution that runs in a desktop client, it uses web requests to communicate with the wallet with the client and makes connecting to games easy and simple. ## HyperPlay Desktop App You will also need to install the hyperplay app which you can find [here](https://www.hyperplay.xyz/downloads) It's a nifty little desktop app that communicates with unity when web requests are sent to it. Once your wallet is logged in to the hyperplay app, when you login or make calls with the SDK, the app will prompt you to interact with your wallet. -![](assets/wallets/hyperplay/hyperplay-app.png) \ No newline at end of file +![](assets/wallets/hyperplay/hyperplay-app.png) diff --git a/docs/v2.6/7_setting-up-an-rpc-node.md b/docs/v2.6/7_setting-up-an-rpc-node.md index c088ab8..c7fd400 100644 --- a/docs/v2.6/7_setting-up-an-rpc-node.md +++ b/docs/v2.6/7_setting-up-an-rpc-node.md @@ -4,8 +4,7 @@ sidebar_position: 7 sidebar_label: Setting Up An RPC Node --- - -# Setting Up An RPC Node For web3.unity +# Setting Up An RPC Node For web3.unity :::info @@ -13,7 +12,7 @@ This section walks through the process of setting up an RPC node to be used with ::: -# Prerequisites +# Prerequisites - A Chainstack account (sign up at [Chainstack](https://console.chainstack.com/user/account/create?utm_campaign=Referrals&utm_source=chainsafe&utm_medium=referrals) if you don't have one) - Familiarity with the web3.unity SDK @@ -26,7 +25,7 @@ This section walks through the process of setting up an RPC node to be used with ![](assets/setting-up-an-rpc-node/chainstack-dashboard.png) -3. Give your project a name and select “Public chain” for the Type. +3. Give your project a name and click create. ![](assets/setting-up-an-rpc-node/chainstack-create-project-name.png) @@ -34,41 +33,41 @@ This section walks through the process of setting up an RPC node to be used with ![](assets/setting-up-an-rpc-node/chainstack-newly-created-project.png) -5. Inside the project, choose "Networks" from the ribbon menu, and then click on “Get Started” to begin deploying an RPC node. +5. Inside the project, click on your network of choice, or the "Explore all Node Options" button to begin deploying an RPC node. ![](assets/setting-up-an-rpc-node/chainstack-get-started-button.png) # Deploying an RPC node -1. After clicking on the “Get started” button, you will be presented with 3 required steps. In the first step “Network details”, you will select the EVM chain that your blockchain game will be making interactions with. +1. After clicking on the "Explore all Node Options" button, you will be presented with 3 required steps. In the first step “Network details”, you will select the EVM chain that your blockchain game will be making interactions with. 2. Depending on which EVM chain you select, you will be prompted to select a network under a given chain. In our example, we have selected Polygon and its Mumbai testnet. Click “Next”. ![](assets/setting-up-an-rpc-node/chainstack-selecting-chain-and-network.png) -3. If you are under Chainstack’s Developer plan, you will only be able to select the default options presented in the “Node deployment” step. This means you will choose “Elastic” for node type, “Full” for full node, “Off” for Debug and trace APIs, “Chainstack” for Hosting, and any available provider under the Cloud provider drop-down menu. Finally, name your node and click “Next”. - -![](assets/setting-up-an-rpc-node/chainstack-join-network.png) +3. If you are under Chainstack’s Developer plan, you will only be able to select the default options presented in the “Node deployment” step. This means you will choose “Elastic” for node type, “Full” for full node. Finally, name your node and click “Next”. -![](assets/setting-up-an-rpc-node/chainstack-naming-node.png) +![](assets/setting-up-an-rpc-node/chainstack-node-deployment.png) :::info -Note that Chainstack’s Developer plan provides 3 million free API requests per month. This should be enough for most testing and app development purposes. If your game requires more calls per month, we would suggest [upgrading your plan](https://console.chainstack.com/user/account/create?utm_campaign=Referrals&utm_source=chainsafe&utm_medium=referrals). +Note that Chainstack’s Developer plan provides 3 million free API requests per month. This should be enough for most testing and app development purposes. If your game requires more calls per month, we would suggest [upgrading your plan](https://console.chainstack.com/user/account/create?utm_campaign=Referrals&utm_source=chainsafe&utm_medium=referrals). ::: 4. Review the details under the “Summary” step and then click “Join network”. -You will appear back in your project dashboard. Your newly created node will take a moment to deploy while under a “Pending” status. + You will appear back in your project dashboard. + +![](assets/setting-up-an-rpc-node/chainstack-join-network.png) -5. Once deployed, the node’s status will turn green under a “Running” status. You can now expand the details of your node by clicking on its name. +5. Once deployed, the node’s status will turn green under a “Running” status. You can now expand the details of your node by clicking on its name. ![](assets/setting-up-an-rpc-node/chainstack-node-status.png) # Retrieving your HTTPS endpoint -1. Within the node dashboard, you will be presented with a number of KPIs and metrics. Please scroll down to the “Access and credentials” section. +1. Within the node dashboard, you will be presented with a number of KPIs and metrics. Please scroll down to the “Access and credentials” section. -2. From here, take note of the HTTPS endpoint, which will be the RPC URL you will use to configure web3.unity and allow your Unity game to interact with the blockchain. +2. From here, take note of the HTTPS endpoint, which will be the RPC URL you will use to configure web3.unity and allow your Unity game to interact with the blockchain. ![](assets/setting-up-an-rpc-node/chainstack-https-endpoints.png) diff --git a/docs/v2.6/8_login-process.md b/docs/v2.6/8_login-process.md index d80ba32..071e598 100644 --- a/docs/v2.6/8_login-process.md +++ b/docs/v2.6/8_login-process.md @@ -9,67 +9,47 @@ sidebar_label: Login Process :::info -This page teaches you how the login process is performed & the how the web3 object is being initialized. +This page teaches you how the login process is performed & how the web3 object is being initialized. ::: -Wallet connections are made as apart of the Web3 object's build process when you log in. Once this build process is complete you'll have an instance and all of it's components with their states fully initialized. This makes using the SDK quite simple as most calls will come from this object. +Wallet connections are made part of the Web3 object's build process when you log in. Once this build process is complete you'll have an instance and all of its components with their states fully initialized. This makes using the SDK quite simple as most calls will come from this object. -```csharp -public class LoginSample : MonoBehaviour -{ - private Web3Builder web3Builder; +## Configuring your Connection Providers - private void Awake() - { - web3Builder = new Web3Builder(ProjectConfigUtilities.Load()) - .Configure(services => - { - // Configure Web3 client to use WalletConnect - services.UseUnityEnvironment() - .UseRpcProvider() - .UseWalletConnect() - .UseWalletConnectSigner() - .UseWalletConnectTransactionExecutor(); - }); - } -} -``` +Before you can connect to a wallet, you need to set up your connection providers. You can do this by going to your `Web3Unity` prefab in your scene hierarchy and look under the Connection Providers drop down in the `ConnectionHandler` script. -Wallet connection happens when `LaunchAsync()` is called on the `Web3Builder` object as seen below. +![img.png](assets/login-process/connection-handler-1.png) -``` csharp -public class LoginSample : MonoBehaviour -{ - . . . - - private Web3 web3; - - public async void Login() - { - web3 = await web3Builder.LaunchAsync(); - } -} -``` +You can add a connection provider of your choice. We currently support Wallet Connect and Metamask in the core package and Web3Auth and HyperPlay as external/add-on packages. Once you've added a connection provider of your choice you can then configure it by further expanding the connection provider. If your connection provider needs further configuration please look [here](/current/choose-your-wallet) on how to configure it. + +![img.png](assets/login-process/connection-handler-2.png) + +## Connecting to a Wallet + +Once you have Configured your connection provider you can drag in `ConnectToWallet.prefab` found in `Packages/io.chainsafe.web3-unity/Runtime/Prefabs/` to connect to a wallet automatically. This prefab has a connect button ready and available that'll initialize building a Web3 object using the connection your choice. You can also use the script `ConnectToWallet` to make your own connection prefab. -You can then use this web3 instance as needed through the SDK which you can see examples of in our sample scripts area [here](/current/sample-scripts). +![img.png](assets/login-process/connect-to-wallet.png)![img.png](assets/login-process/connect-to-wallet-2.png) -``` csharp -public class LoginSample : MonoBehaviour +If you would like to connect to a wallet manually, you can follow the steps below. + +```csharp +public class ConnectToWallet : MonoBehaviour { - . . . - - public string GetPlayerAddress() + private async void Start() { - return Web3Accessor.Web3.Signer.PublicAddress; + await Web3Unity.Instance.Initialize(true); + + await Web3Unity.Instance.Connect(); + + if (Web3Unity.Connected) + { + Debug.Log("Connected"); + + var web3 = Web3Unity.Web3; + } } } ``` -Whilst we go into the core functionality of the build process here, if you simply want to use the login scene provided -with the samples, it will do everything here in the login process so you don't need to worry. Just add a LoginProvider -of your choice and you're good to go. - -![](assets/login-process/login-scene.png) - -You can then access the Web3 client that was build by LoginProvider with a static `Web3Accessor.Web3` property. \ No newline at end of file +You can replace `WalletConnectConnectionProvider` with any other connection provider available, If a connection provider doesn't exist you can also implement your own by inheriting from the `ConnectionProvider` class. Once connected you can access the instantiated Web3 via `Web3Unity.Web3`. diff --git a/docs/v2.6/9_sample-scripts-and-chain-interactions.md b/docs/v2.6/9_sample-scripts-and-chain-interactions.md index 092ad86..e969cf4 100644 --- a/docs/v2.6/9_sample-scripts-and-chain-interactions.md +++ b/docs/v2.6/9_sample-scripts-and-chain-interactions.md @@ -6,1748 +6,196 @@ sidebar_label: Sample Scripts & Chain Interactions # Sample Scripts & Chain Interactions -:::info +## Reading and writing to the blockchain +The fastest and most convenient way to do any blockchain interaction would be to first generate the C# class from the contracts ABI, which is described in the section above. -In order to copy and paste the scripts below without hassle you will need to have the sample package imported via unity package manager. If you need to install the core SDK sample package you can follow the install guide in our getting started section [here](https://docs.gaming.chainsafe.io/current/getting-started). -::: - -### The login scene -You'll notice when you import the samples into the project that some scenes are added to your build configuration. You'll want to keep the login scene as the first scene as it's needed to initialize web3 to create a wallet connection. You can remove the rest and add a blank scene as your 2nd scene in build settings. We'll use this 2nd scene to drop scripts in and out of for testing purposes. Make sure your 2nd scene has an event system present in the hierarchy or the scripts won't work. You can right click in the object hierarchy on the left and go to UI -> Event system to add one if it isn't there. - -### Adding a script to a scene for testing -If you right click in the unity explorer you can create a c# script. For example we're going to test erc20NameOf to get the name of an ERC20 token from chain data. Right click in the editor file explorer and create a new script, attach this script to an empty object in the scene next to the editor system. Name the script erc20NameOf, place the code below into it and press save. Once saved you can go back to the editor, create a button and assign the scripts public function to a button press event on the right. You can do this by finding the objects properties on the right, scrolling down to button and adding an event. Just drag the object with the script into the button event area and choose the starting function of the script. - -## ERC20 Sample Scripts - -### Name Of -Fetches the name of an ERC20 contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the name of an ERC20 contract -/// -public class Erc20NameOf : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - - // Function - public async void Name() - { - var name = await Web3Accessor.Web3.Erc20.GetName(contractAddress); - SampleOutputUtil.PrintResult(name, "ERC-20", nameof(Erc20Service.GetName)); - // You can make additional changes after this line - } -} -``` - -### Symbol -Fetches the symbol of an ERC20 contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the symbol of an ERC20 contract -/// -public class Erc20Symbol : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - - // Function - public async void Symbol() - { - var symbol = await Web3Accessor.Web3.Erc20.GetSymbol(contractAddress); - SampleOutputUtil.PrintResult(symbol, "ERC-20", nameof(Erc20Service.GetSymbol)); - // You can make additional changes after this line - } -} -``` - -### Decimals -Fetches the decimals of an ERC20 contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the decimals of an ERC20 contract -/// -public class Erc20Decimals : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - - // Function - public async void Decimals() - { - var decimals = await Web3Accessor.Web3.Erc20.GetDecimals(contractAddress); - SampleOutputUtil.PrintResult(decimals.ToString(), "ERC-20", nameof(Erc20Service.GetDecimals)); - // You can make additional changes after this line - } -} -``` - -### Total Supply -Fetches the total supply of an ERC20 token. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the total supply of an ERC20 contract -/// -public class Erc20TotalSupply : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - - // Function - public async void TotalSupply() - { - var totalSupply = await Web3Accessor.Web3.Erc20.GetTotalSupply(contractAddress); - SampleOutputUtil.PrintResult(totalSupply.ToString(), "ERC-20", nameof(Erc20Service.GetTotalSupply)); - // You can make additional changes after this line - } -} -``` - -### Balance Of -Fetches the balance of an ERC20 token from an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the balance of an ERC20 token from an account -/// -public class Erc20BalanceOf : MonoBehaviour -{ - // Sets the account to be queried, you can change this to be any address - string account = Web3Accessor.Web3.Signer.PublicAddress; - //Set the contract address to be queried - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - - // Function - public async void BalanceOf() - { - var balance = await Web3Accessor.Web3.Erc20.GetBalanceOf(contractAddress, account); - SampleOutputUtil.PrintResult(balance.ToString(), "ERC-20", nameof(Erc20Service.GetBalanceOf)); - // You can make additional changes after this line - } -} -``` - -### Native Balance Of -Fetches the native balance of an ERC20 token from an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Providers; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the native balance of an ERC20 token from an account. -/// -public class Erc20NativeBalanceOf : MonoBehaviour -{ - public async void NativeBalanceOf() - { - // Sets the account to be queried, you can change this to be any address - string account = Web3Accessor.Web3.Signer.PublicAddress; - var balance = await Web3Accessor.Web3.RpcProvider.GetBalance(account); - SampleOutputUtil.PrintResult(balance.ToString(), "Native Balance Of"); - // You can make additional changes after this line - } -} -``` - -### Mint -Mints ERC20 tokens to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Mints ERC20 tokens to an account -/// -public class Erc20Mint : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - private BigInteger amount = 1; - - // Function - public async void MintErc20() - { - // Sets the account to mint to, you can change this to be any address - string toAccount = Web3Accessor.Web3.Signer.PublicAddress; - var mintResponse = await Web3Accessor.Web3.Erc20.Mint(ChainSafeContracts.Erc20, amountMint, toAccount); - var output = SampleOutputUtil.BuildOutputValue(mintResponse); - SampleOutputUtil.PrintResult(output, "ERC-20", nameof(Erc20Service.Mint)); - // You can make additional changes after this line - } -} -``` - -### Transfer -Transfers ERC20 tokens to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Transfers ERC20 tokens to an account -/// -public class Erc20Transfer : MonoBehaviour -{ - // Variables - private string contractAddress = "0x358969310231363CBEcFEFe47323139569D8a88b"; - private string toAccount = "0xdD4c825203f97984e7867F11eeCc813A036089D1"; - private BigInteger amount = 1000000000000000; - - // Function - public async void TransferErc20() - { - var mintResponse = await Web3Accessor.Web3.Erc20.Transfer(contractAddress, toAccount, amountTransfer); - var output = SampleOutputUtil.BuildOutputValue(mintResponse); - SampleOutputUtil.PrintResult(output, "ERC-20", nameof(Erc20Service.Transfer)); - // You can make additional changes after this line - } -} -``` - -## ERC721 Sample Scripts - -### Balance Of -Fetches the balance of ERC721 NFTs from an account - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the balance of ERC721 NFTs from an account -/// -public class Erc721BalanceOf : MonoBehaviour -{ - // Variables - private string contractAddress = "0x4f75BB7bdd6f7A0fD32f1b3A94dfF409F5a3F1CC"; - - // Function - public async void BalanceOf() - { - // Sets the account to be queried, you can change this to be any address - string account = Web3Accessor.Web3.Signer.PublicAddress; - var balance = await Web3Accessor.Web3.Erc721.GetBalanceOf(contractAddress, account); - SampleOutputUtil.PrintResult(balance.ToString(), "ERC-721", nameof(Erc721Service.GetBalanceOf)); - // You can make additional changes after this line - } -} -``` - -### Owner Of -Fetches the owner of an ERC721 token id. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the owner of an ERC721 token id -/// -public class Erc721OwnerOf : MonoBehaviour -{ - // Variables - private string contractAddress = "0x4f75BB7bdd6f7A0fD32f1b3A94dfF409F5a3F1CC"; - private string tokenId = "1"; - - // Function - public async void OwnerOf() - { - var owner = await Web3Accessor.Web3.Erc721.GetOwnerOf(contractAddress, tokenIdOwnerOf); - SampleOutputUtil.PrintResult(owner, "ERC-721", nameof(Erc721Service.GetOwnerOf)); - // You can make additional changes after this line - } -} -``` - -### Owner Of Batch -Fetches the owners of ERC721 token ids. - -``` csharp -using UnityEngine; -using System.Linq; -using System.Text; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the owners of ERC721 token ids -/// -public class Erc721OwnerOfBatch : MonoBehaviour -{ - // Variables - private string contractAddress = "0x4f75BB7bdd6f7A0fD32f1b3A94dfF409F5a3F1CC"; - private string[] tokenIds = { "4", "6" }; - - // Function - public async void OwnerOfBatch() - { - var owners = await Web3Accessor.Web3.Erc721.GetOwnerOfBatch(contractAddress, tokenIds); - var ownersString = new StringBuilder(); - var dict = owners.GroupBy(x => x.Owner).ToDictionary(x => x.Key, x => x.Select(x => x.TokenId).ToList()); - foreach (var owner in dict) - { - ownersString.AppendLine($"Owner: {owner.Key} owns the following token(s):"); - foreach (var tokenId in owner.Value) - { - ownersString.AppendLine("\t" + tokenId); - } - } - SampleOutputUtil.PrintResult(ownersString.ToString(), "ERC-721", nameof(Erc721Service.GetOwnerOfBatch)); - // You can make additional changes after this line - } -} -``` - -### Uri -Fetches the URI from an ERC721 NFT. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the URI from an ERC721 NFT -/// -public class Erc721Uri : MonoBehaviour -{ - // Variables - private string contractAddress = "QmfUHuFj3YL2JMZkyXNtGRV8e9aLJgQ6gcSrqbfjWFvbqQ"; - private string tokenId = "1"; - - // Function - public async void Uri() - { - var uri = await Web3Accessor.Web3.Erc721.GetUri(contractAddress, tokenId); - SampleOutputUtil.PrintResult(uri, "ERC-721", nameof(Erc721Service.GetUri)); - // You can make additional changes after this line - } -} -``` - -### Mint 721 -Mints a 721 NFT to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Mints a 721 NFT to an account -/// -public class Erc721Mint : MonoBehaviour -{ - // Variables - private string contractAddress = "0x4f75BB7bdd6f7A0fD32f1b3A94dfF409F5a3F1CC"; - private string uri = "QmfUHuFj3YL2JMZkyXNtGRV8e9aLJgQ6gcSrqbfjWFvbqQ"; - - // Function - public async void MintErc721() - { - var response = await Web3Accessor.Web3.Erc721.Mint(contractAddress, uri); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, "ERC-721", nameof(Erc721Service.GetUri)); - // You can make additional changes after this line - } -} -``` - -### Transfer -Transfers an ERC721 token to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Transfers an ERC721 token to an account -/// -public class Erc721Transfer : MonoBehaviour -{ - // Variables - private string contractAddress = "0x4f75BB7bdd6f7A0fD32f1b3A94dfF409F5a3F1CC"; - private string toAccount = "0xdD4c825203f97984e7867F11eeCc813A036089D1"; - private BigInteger tokenId = 1; - - // Function - public async void TransferErc721() - { - var response = await Web3Accessor.Web3.Erc721.Transfer(contractAddress, toAccount, tokenId); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, "ERC-721", nameof(Erc721Service.Transfer)); - // You can make additional changes after this line - } -} -``` - -## ERC1155 Sample Scripts - -### Balance Of -Fetches the balance of ERC1155 NFTs from an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the balance of ERC1155 NFTs from an account -/// -public class Erc1155BalanceOf : MonoBehaviour -{ - // Variables - // Sets the account to be queried, you can change this to be any address - private string account = Web3Accessor.Web3.Signer.PublicAddress; - private string contractAddress = "0xAA2EbE78aa788d13AfFaaefD38C93333bbC4d51e"; - private string tokenId = "1"; - - // Function - public async void BalanceOf() - { - var balance = await Web3Accessor.Web3.Erc1155.GetBalanceOf( - ChainSafeContracts.Erc1155, - tokenIdBalanceOf, - account); - SampleOutputUtil.PrintResult(balance.ToString(), "ERC-1155",nameof(Erc1155Service.GetBalanceOf)); - // You can make additional changes after this line - } -} -``` - -### Balance Of Batch -Fetches the balance of ERC1155 NFTs from multiple accounts. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the balance of ERC1155 NFTs from multiple accounts -/// -public class Erc1155BalanceOfBatch : MonoBehaviour -{ - // Variables - private string contractAddress = "0xdc4aff511e1b94677142a43df90f948f9ae181dd"; - private string[] accounts = { "0xd25b827D92b0fd656A1c829933e9b0b836d5C3e2", "0xE51995Cdb3b1c109E0e6E67ab5aB31CDdBB83E4a" }; - private string[] tokenIds = { "1", "2" }; - - public async void BalanceOfBatch() - { - var balances = await Web3Accessor.Web3.Erc1155.GetBalanceOfBatch( - contractAddress, - accounts, - tokenIds); - SampleOutputUtil.PrintResult(string.Join(", ", balances), "ERC-1155",nameof(Erc1155Service.GetBalanceOfBatch)); - // You can make additional changes after this line - } -} -``` - -### Import Texture -Fetches the texture of an ERC1155 NFT and displays it to a raw image. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the texture of an ERC1155 NFT and displays it to a raw image -/// -public class Erc1155ImportTexture : MonoBehaviour -{ - // Variables - // You need to assign this raw image object in the editor - public RawImage rawImage; - private string contractAddress = "0xAA2EbE78aa788d13AfFaaefD38C93333bbC4d51e"; - private string tokenId = "1"; - - // Function - public async void ImportNftTexture1155() - { - var texture = await Web3Accessor.Web3.Erc1155.ImportTexture(ChainSafeContracts.Erc1155, tokenIdTexture); - rawImage.texture = texture; - // You can make additional changes after this line - } -} -``` - -### Uri -Fetches the URI from an ERC1155 NFT. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Fetches the URI from an ERC1155 NFT -/// -public class Erc1155Uri : MonoBehaviour -{ - // Variables - private string contractAddress = "0xAA2EbE78aa788d13AfFaaefD38C93333bbC4d51e"; - private string tokenId = "1"; - - // Function - public async void Uri() - { - var uri = await Web3Accessor.Web3.Erc1155.GetUri( - ChainSafeContracts.Erc1155, - tokenIdUri); - SampleOutputUtil.PrintResult(uri, "ERC-1155",nameof(Erc1155Service.GetUri)); - // You can make additional changes after this line - } -} -``` - -### Mint 1155 -Mints a 1155 NFT to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; -using System.Numerics; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Mints a 1155 NFT to an account -/// -public class Erc1155Mint : MonoBehaviour -{ - // Variables - private string contractAddress = "0xAA2EbE78aa788d13AfFaaefD38C93333bbC4d51e"; - private BigInteger id = 1; - private BigInteger amount = 1; - - // Function - public async void MintErc1155() - { - var response = await Web3Accessor.Web3.Erc1155.Mint( - contractAddress, - id, - amount); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, "ERC-1155",nameof(Erc1155Service.Mint)); - // You can make additional changes after this line - } -} -``` - -### Transfer -Transfer ERC1155 tokens to an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Transfer ERC1155 tokens to an account -/// -public class Erc1155Transfer : MonoBehaviour -{ - // Variables - private string toAccount = "0xdD4c825203f97984e7867F11eeCc813A036089D1"; - private string contract = "0xAA2EbE78aa788d13AfFaaefD38C93333bbC4d51e"; - private BigInteger tokenId = 1; - private BigInteger amount = 1; - - // Function - public async void TransferErc1155() - { - var response = await Web3Accessor.Web3.Erc1155.Transfer( - contract, - tokenId, - amount, - toAccount); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, "ERC-1155",nameof(Erc1155Service.Transfer)); - // You can make additional changes after this line - } -} -``` - -## EVM Sample Scripts - -### IPFS Upload -Uploads to IPFS, you will need to obtain your storage API secret and bucket id from ChainSafe's storage [here](https://app.storage.chainsafe.io/). - -``` csharp -using UnityEngine; -using System.Collections.Generic; -using ChainSafe.Gaming.UnityPackage.Model; -using ChainSafe.Gaming.Marketplace; - -public class IPFSCalls : MonoBehaviour -{ - #region Fields - - [Header("IPFS VALUES")] - [SerializeField] private string apiSecretKey = "Fill In Your API Secret Key From Storage"; - [SerializeField] private string bucketId = "Fill In Your Bucket ID From Storage"; - [SerializeField] private string fileNameImage = "Logo.png"; - [SerializeField] private string fileNameMetaData = "MetaData.json"; - [SerializeField] private string nftName = "Name of the NFT"; - [SerializeField] private string description = "An NFT description"; - [SerializeField] private string externalUrl = "The URL that appears below your assets image"; - [SerializeField] private List display_types = new List { "Stamina", "Boost Number" }; - [SerializeField] private List trait_types = new List { "Health", "Thunder Power" }; - [SerializeField] private List values = new List { "5", "20" }; - [Header("Required for image only upload")] - [SerializeField] private string imageCID = "Enter your image CID from storage or upload call"; - - #endregion - - #region Methods - - /// - /// Uploads an image selected by the user to IPFS - /// - public async void IPFSUploadImage() - { - var uploadRequest = new IPFSUploadRequestModel - { - ApiKey = apiSecretKey, - BucketId = bucketId, - FileNameImage = fileNameImage - }; - var cid = await IPFS.UploadImage(uploadRequest); - Debug.Log($"Image uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"); - } - - /// - /// Uploads metadata to IPFS - /// - public async void IPFSUploadMetadata() - { - var uploadRequest = new IPFSUploadRequestModel - { - ApiKey = apiSecretKey, - BucketId = bucketId, - Image = imageCID, - FileNameMetaData = fileNameMetaData, - Name = nftName, - Description = description, - External_url = externalUrl, - attributes = IPFS.CreateAttributesList(display_types, trait_types, values) - }; - var cid = await IPFS.UploadMetaData(uploadRequest); - Debug.Log($"Metadata uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"); - } - - /// - /// Uploads an image selected by the user including metadata to IPFS - /// - public async void IPFSUploadImageAndMetadata() - { - var uploadRequest = new IPFSUploadRequestModel - { - ApiKey = apiSecretKey, - BucketId = bucketId, - FileNameImage = fileNameImage, - FileNameMetaData = fileNameMetaData, - Name = name, - Description = description, - External_url = externalUrl, - attributes = IPFS.CreateAttributesList(display_types, trait_types, values) - }; - var cid = await IPFS.UploadImageAndMetadata(uploadRequest); - Debug.Log($"Image & metadata uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"); - } - - #endregion -} - -``` - -### Marketplace Calls -Makes reads and writes to and from ChainSafe's marketplace. - -``` csharp -using UnityEngine; -#if MARKETPLACE_AVAILABLE -using Scripts.EVM.Marketplace; -using UnityEngine; - -/// -/// Marketplace sample calls for use with the api documentation. -/// Marketplace Api: https://docs.gaming.chainsafe.io/marketplace-api/docs/marketplaceapi -/// Token Api: https://docs.gaming.chainsafe.io/token-api/docs/tokenapi -/// -public class MarketplaceCalls : MonoBehaviour -{ - #region fields - [Header("Change the fields below for testing purposes")] - - [Header("Bearer token")] - [SerializeField] private string bearerToken = "Please set your bearer token from the ChainSafe dashboard"; - - [Header("721 Collection Call")] - [SerializeField] private string collectionId721 = "Set 721 collection ID"; - - [Header("1155 Collection Call")] - [SerializeField] private string collectionId1155 = "Set 1155 collection ID"; - - [Header("Marketplace Calls")] - [SerializeField] private string marketplaceId = "Set marketplace ID"; - - [Header("Token Calls")] - [SerializeField] private string tokenId = "Set token ID i.e 1"; - - [Header("Create 721 Collection Call")] - [SerializeField] private string collectionName721 = "Set 721 collection name"; - [SerializeField] private string collectionDescription721 = "Set 721 collection description"; - [SerializeField] private bool collectionMintingPublic721 = false; - - [Header("Create 1155 Collection Call")] - [SerializeField] private string collectionName1155 = "Set 1155 collection name"; - [SerializeField] private string collectionDescription1155 = "Set 1155 collection description"; - [SerializeField] private bool collectionMintingPublic1155 = false; - - [Header("Delete calls (Can only be used before the item is on chain)")] - [SerializeField] private string collectionToDelete = "Set collection to delete"; - [SerializeField] private string marketplaceToDelete = "Set marketplace to delete"; - - [Header("Mint 721 to collection calls")] - [SerializeField] private string collectionContract721 = "Set 721 collection to mint to"; - [SerializeField] private string uri721 = "Set metadata uri with full path i.e. https://ipfs.chainsafe.io/ipfs/bafyjvzacdj4apx52hvbyjkwyf7i6a7t3pcqd4kw4xxfc67hgvn3a"; - - [Header("Mint 1155 to collection calls")] - [SerializeField] private string collectionContract1155 = "Set 1155 collection to mint to"; - [SerializeField] private string uri1155 = "Set metadata uri with full path i.e. https://ipfs.chainsafe.io/ipfs/bafyjvzacdj4apx52hvbyjkwyf7i6a7t3pcqd4kw4xxfc67hgvn3a"; - [SerializeField] private string amount1155 = "Set amount of Nfts to mint i.e 1"; - - [Header("Create marketplace call")] - [SerializeField] private string marketplaceName = "Set marketplace name"; - [SerializeField] private string marketplaceDescription = "Set marketplace description"; - [SerializeField] private bool marketplaceWhitelisting = false; - - [Header("List to marketplace calls")] - [SerializeField] private string tokenIdToList = "Set token ID to list"; - [SerializeField] private string weiPriceToList = "Set price in wei to list for i.e 100000000000000"; - [SerializeField] private string marketplaceContractToListTo = "Set marketplace contract to list to"; - [SerializeField] private string collectionContractToList = "Set collection contract to list from"; - - [Header("List to marketplace calls")] - [SerializeField] private string marketplaceContractToBuyFrom = "Set marketplace contract to buy from"; - [SerializeField] private string tokenIdToBuy = "Set token ID to buy"; - [SerializeField] private string weiPriceToBuy = "Set price in wei to buy with i.e 100000000000000"; - - #endregion - - #region Methods - - /// - /// Gets all items in a project. - /// - public async void GetProjectItems() - { - var response = await Marketplace.GetProjectItems(); - Debug.Log($"Total: {response.total}"); - foreach (var item in response.items) - { - Marketplace.PrintObject(item); - } - } - - /// - /// Gets all items in a marketplace. - /// - public async void GetMarketplaceItems() - { - var response = await Marketplace.GetMarketplaceItems(marketplaceId); - Debug.Log($"Total: {response.total}"); - foreach (var item in response.items) - { - Marketplace.PrintObject(item); - } - } - - /// - /// Gets items listed by token id. - /// - public async void GetItem() - { - var response = await Marketplace.GetItem(marketplaceId, tokenId); - Marketplace.PrintObject(response.token); - } - - /// - /// Gets all tokens in a project. - /// - public async void GetProjectTokens() - { - var response = await Marketplace.GetProjectTokens(); - foreach (var token in response.tokens) - { - Marketplace.PrintObject(token); - } - } - - /// - /// Gets all tokens in a 721 collection. - /// - public async void GetCollectionTokens721() - { - var response = await Marketplace.GetCollectionTokens721(collectionId721); - foreach (var token in response.tokens) - { - Marketplace.PrintObject(token); - } - } - - /// - /// Gets all tokens in a 1155 collection. - /// - public async void GetCollectionTokens1155() - { - var response = await Marketplace.GetCollectionTokens1155(collectionId1155); - foreach (var token in response.tokens) - { - Marketplace.PrintObject(token); - } - } - - /// - /// Gets the information of a token in a collection via id. Token id is optional. - /// - public async void GetCollectionToken() - { - var response = await Marketplace.GetCollectionToken(collectionId721, tokenId); - Marketplace.PrintObject(response); - } - - /// - /// Gets the owners of a token id in a collection. - /// - public async void GetTokenOwners() - { - var response = await Marketplace.GetTokenOwners(collectionId1155, tokenId); - foreach (var owner in response.owners) - { - Marketplace.PrintObject(owner); - } - } - - /// - /// Creates a 721 collection - /// - public async void Create721Collection() - { - var data = await Marketplace.Create721Collection(bearerToken, collectionName721, collectionDescription721, collectionMintingPublic721); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Creates a 1155 collection - /// - public async void Create1155Collection() - { - var data = await Marketplace.Create1155Collection(bearerToken, collectionName1155, collectionDescription1155, collectionMintingPublic1155); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Mints an NFT to a 721 collection - /// - public async void Mint721CollectionNft() - { - var data = await Marketplace.Mint721CollectionNft(collectionContract721, uri721); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Mints an NFT to a 1155 collection - /// - public async void Mint1155CollectionNft() - { - var data = await Marketplace.Mint1155CollectionNft(collectionContract1155, uri1155, amount1155); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Deletes a collection that isn't on chain yet - /// - public async void DeleteCollection() - { - var response = await Marketplace.DeleteCollection(bearerToken, collectionToDelete); - Debug.Log(response); - } - - /// - /// Creates a marketplace - /// - public async void CreateMarketplace() - { - var data = await Marketplace.CreateMarketplace(bearerToken, marketplaceName, marketplaceDescription, marketplaceWhitelisting); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Deletes a marketplace that isn't on chain yet - /// - public async void DeleteMarketplace() - { - var response = await Marketplace.DeleteMarketplace(bearerToken,marketplaceToDelete); - Debug.Log(response); - } - - /// - /// Approves marketplace to list tokens - /// - public async void ApproveListNftsToMarketplace() - { - var data = await Marketplace.SetApprovalMarketplace(collectionContractToList, marketplaceContractToListTo, "1155",true); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Revokes approval from marketplace to list tokens - /// - public async void RevokeApprovalListNftsToMarketplace() - { - var data = await Marketplace.SetApprovalMarketplace(collectionContractToList, marketplaceContractToListTo, "1155",false); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Lists NFTs to the marketplace - /// - public async void ListNftsToMarketplace() - { - var data = await Marketplace.ListNftsToMarketplace(marketplaceContractToListTo,collectionContractToList, tokenIdToList, weiPriceToList); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - /// - /// Purchases an Nft from the marketplace - /// - public async void PurchaseNftFromMarketplace() - { - var data = await Marketplace.PurchaseNft(marketplaceContractToBuyFrom, tokenIdToBuy, weiPriceToBuy); - var response = SampleOutputUtil.BuildOutputValue(data); - Debug.Log($"TX: {response}"); - } - - #endregion -} -#endif -``` - -### Contract Call -Makes a read call to a contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Makes a read call to a contract -/// -public class CallContract : MonoBehaviour -{ - // Variables - private string abi = "[ { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"_myArg\", \"type\": \"uint256\" } ], \"name\": \"addTotal\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }, { \"inputs\": [], \"name\": \"getStore\", \"outputs\": [ { \"internalType\": \"string[]\", \"name\": \"\", \"type\": \"string[]\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" } ], \"name\": \"myTotal\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"string[]\", \"name\": \"_addresses\", \"type\": \"string[]\" } ], \"name\": \"setStore\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; - private string contract = "0x9839293240C535d8009920390b4D3DA256d31177"; - private string method = "myTotal"; - - // Function - public async void ContractCall() - { - object[] args = - { - Web3Accessor.Web3.Signer.PublicAddress - }; - var response = await Evm.ContractCall(Web3Accessor.Web3, method, abi, contract, args); - Debug.Log(response); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, nameof(Evm), nameof(Evm.ContractCall)); - // You can make additional changes after this line - } -} -``` - -### Contract Send -Makes a write call to a contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Makes a write call to a contract -/// -public class SendContract : MonoBehaviour -{ - // Variables - private string abi = "[ { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"_myArg\", \"type\": \"uint256\" } ], \"name\": \"addTotal\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }, { \"inputs\": [], \"name\": \"getStore\", \"outputs\": [ { \"internalType\": \"string[]\", \"name\": \"\", \"type\": \"string[]\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" } ], \"name\": \"myTotal\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"string[]\", \"name\": \"_addresses\", \"type\": \"string[]\" } ], \"name\": \"setStore\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; - private string contract = "0x9839293240C535d8009920390b4D3DA256d31177"; - private string method = "addTotal"; - private int increaseAmount = 1; - // Value for sending native tokens with a transaction for payable functions - // To use just add "value" as the last parameter of evm.ContractSend - // private HexBigInteger value = new HexBigInteger(1000000000000000); - - // Function - public async void ContractSend() - { - object[] args = - { - increaseAmount - }; - var response = await Evm.ContractSend(Web3Accessor.Web3, method, abi, contract, args); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, nameof(Evm), nameof(Evm.ContractSend)); - // You can make additional changes after this line - } -} -``` - -### Get Array -Gets an array response from a contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets an array response from a contract -/// -public class GetArray : MonoBehaviour -{ - // Variables - private string abi = "[ { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"_myArg\", \"type\": \"uint256\" } ], \"name\": \"addTotal\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }, { \"inputs\": [], \"name\": \"getStore\", \"outputs\": [ { \"internalType\": \"string[]\", \"name\": \"\", \"type\": \"string[]\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" } ], \"name\": \"myTotal\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"string[]\", \"name\": \"_addresses\", \"type\": \"string[]\" } ], \"name\": \"setStore\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; - private string contract = "0x9839293240C535d8009920390b4D3DA256d31177"; - private string method = "getStore"; - - // Function - public async void GetArrayCall() - { - var response = await Evm.GetArray(Web3Accessor.Web3, contract, abi, method); - var responseString = string.Join(",\n", response.Select((list, i) => $"#{i} {string.Join((string)", ", (IEnumerable)list)}")); - SampleOutputUtil.PrintResult(responseString, nameof(Evm), nameof(Evm.GetArray)); - // You can make additional changes after this line - } -} -``` - -### Send Array -Sends an array to a contract. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Sends an array to a contract -/// -public class SendArray : MonoBehaviour -{ - // Variables - private string abi = "[ { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"_myArg\", \"type\": \"uint256\" } ], \"name\": \"addTotal\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }, { \"inputs\": [], \"name\": \"getStore\", \"outputs\": [ { \"internalType\": \"string[]\", \"name\": \"\", \"type\": \"string[]\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" } ], \"name\": \"myTotal\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"string[]\", \"name\": \"_addresses\", \"type\": \"string[]\" } ], \"name\": \"setStore\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; - private string contract = "0x9839293240C535d8009920390b4D3DA256d31177"; - private string method = "setStore"; - private string[] stringArray = - { - "0xFb3aECf08940785D4fB3Ad87cDC6e1Ceb20e9aac", - "0x92d4040e4f3591e60644aaa483821d1bd87001e3" - }; - - // Function - public async void SendArrayCall() - { - var response = await Evm.SendArray(Web3Accessor.Web3, method, abi, contract, stringArray); - var output = SampleOutputUtil.BuildOutputValue(response); - SampleOutputUtil.PrintResult(output, nameof(Evm), nameof(Evm.SendArray)); - // You can make additional changes after this line - } -} -``` - -### Get Block Number -Gets the current block number. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets the current block number -/// -public class GetBlockNumber : MonoBehaviour -{ - // Function - public async void GetBlockNumberCall() - { - var blockNumber = await Evm.GetBlockNumber(Web3Accessor.Web3); - SampleOutputUtil.PrintResult(blockNumber.ToString(), nameof(Evm), nameof(Evm.GetBlockNumber)); - // You can make additional changes after this line - } -} -``` - -### Get Gas Limit -Gets the current gas limit. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets the current gas limit -/// -public class GetGasLimit : MonoBehaviour -{ - // Variables - private string abi = "[ { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"_myArg\", \"type\": \"uint256\" } ], \"name\": \"addTotal\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" }, { \"inputs\": [], \"name\": \"getStore\", \"outputs\": [ { \"internalType\": \"string[]\", \"name\": \"\", \"type\": \"string[]\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"address\", \"name\": \"\", \"type\": \"address\" } ], \"name\": \"myTotal\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"string[]\", \"name\": \"_addresses\", \"type\": \"string[]\" } ], \"name\": \"setStore\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; - private string contract = "0x9839293240C535d8009920390b4D3DA256d31177"; - private string method = "addTotal"; - private int increaseAmount = 1; - - public async void GetGasLimitCall() - { - object[] args = - { - increaseAmount - }; - var gasLimit = await Evm.GetGasLimit(Web3Accessor.Web3, abi, contract, method, args); - SampleOutputUtil.PrintResult(gasLimit.ToString(), nameof(Evm), nameof(Evm.GetGasLimit)); - } -} -``` - -### Get Gas Price -Gets the current gas price. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets the current gas price -/// -public class GetGasPrice : MonoBehaviour -{ - // Function - public async void GetGasPriceCall() - { - var gasPrice = await Evm.GetGasPrice(Web3Accessor.Web3); - SampleOutputUtil.PrintResult(gasPrice.ToString(), nameof(Evm), nameof(Evm.GetGasPrice)); - // You can make additional changes after this line - } -} -``` - -### Get Nonce -Gets the current nonce for an account. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets the current nonce for an account -/// -public class GetNonce : MonoBehaviour -{ - // Function - public async void GetNonceCall() - { - var nonce = await Evm.GetNonce(Web3Accessor.Web3); - SampleOutputUtil.PrintResult(nonce.ToString(), nameof(Evm), nameof(Evm.GetNonce)); - // You can make additional changes after this line - } -} -``` - -### SHA3 -Encrypts a message with SHA3. - -``` csharp -using UnityEngine; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Encrypts a message with SHA3 -/// -public class Sha3 : MonoBehaviour -{ - // Variables - private string message = "It’s dangerous to go alone, take this!"; - - // Function - public void Sha3Call() - { - var hash = Evm.Sha3(message); - SampleOutputUtil.PrintResult(hash, nameof(Evm), nameof(Evm.Sha3)); - // You can make additional changes after this line - } -} -``` - -### Sign Message -Signs a message, the response is unique for each user. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Signs a message, the response is unique for each user -/// -public class SignMessage : MonoBehaviour -{ - // Variables - private string message = "The right man in the wrong place can make all the difference in the world."; - - // Function - public async void SignMessageCall() - { - var signedMessage = await Evm.SignMessage(Web3Accessor.Web3, message); - SampleOutputUtil.PrintResult(signedMessage, nameof(Evm), nameof(Evm.SignMessage)); - // You can make additional changes after this line - } -} -``` - -### Sign Verify -Verifies a users account via message sign. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Verifies a users account via message sign -/// -public class SignVerify : MonoBehaviour +```csharp +public class CustomContractSample : MonoBehaviour { - // Variables - private string message = "A man chooses, a slave obeys."; - - // Function - public async void SignVerifyCall() - { - var signatureVerified = await Evm.SignVerify(Web3Accessor.Web3, message); - var output = signatureVerified ? "Verified" : "Failed to verify"; - SampleOutputUtil.PrintResult(output, nameof(Evm), nameof(Evm.SignVerify)); - // You can make additional changes after this line - } -} -``` + [SerializeField] private string contractAddress; -### Send Transaction -Sends a transaction. + Erc20Contract _erc20Contract; -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; + public async void Start() + { + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ + _erc20Contract = await Web3Unity.Instance.BuildContract(contractAddress); + } -/// -/// Sends a transaction -/// -public class SendTransaction : MonoBehaviour -{ - // Variables - private string toAddress = "0xdD4c825203f97984e7867F11eeCc813A036089D1"; - - //Function - public async void SendTransactionCall() + public async string BalanceOf(string address) { - var transactionHash = await Evm.SendTransaction(Web3Accessor.Web3, toAddress); - SampleOutputUtil.PrintResult(transactionHash, nameof(Evm), nameof(Evm.SendTransaction)); - // You can make additional changes after this line + return await _erc20Contract.BalanceOf(address); } -} -``` - -### Get Transaction Status -Gets the status of a transaction. - -``` csharp -using UnityEngine; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Gets the status of a transaction -/// -public class GetTransactionStatus : MonoBehaviour -{ - // Function - public async void GetTransactionStatusCall() + public async void Transfer(string destinationAddress, BigInteger amount) { - var receipt = await Evm.GetTransactionStatus(Web3Accessor.Web3); - var output = $"Confirmations: {receipt.Confirmations}," + - $" Block Number: {receipt.BlockNumber}," + - $" Status {receipt.Status}"; + await _erc20.Transfer(destinationAddress, amount); + } - SampleOutputUtil.PrintResult(output, nameof(Evm), nameof(Evm.GetTransactionStatus)); - // You can make additional changes after this line + public async void OnDestroy() + { + await _erc20Contract.DisposeAsync(); } + + } ``` +If for example you try to call the Transfer method and you don't have the wallet connected to your current session, you will get an exception that the signer is not bound. And if you're in the SampleMain scene, you'd be greeted with the Wallet Connection popup. -### Get Event Data Via Transaction Receipt +If, for whatever reason, you still want to use the old way of communicating with the Blockchain, we still recommend you to generate the C# class first and then you can do the following: ```csharp -using UnityEngine; -using System.Linq; -using System.Numerics; -using ChainSafe.Gaming.Evm.Contracts.Extensions; -using ChainSafe.Gaming.UnityPackage; -using Nethereum.ABI.FunctionEncoding.Attributes; -using Nethereum.RPC.Eth.DTOs; -using Newtonsoft.Json; -using Scripts.EVM.Token; - -/// -/// Class for the event data that we're calling, this must match the solidity event i.e. event AmountIncreased(address indexed wallet, uint256 amount); -/// -[Event("AmountIncreased")] -public class AmountIncreasedEvent : IEventDTO +public class CustomContractSample : MonoBehaviour { - [Parameter("address", "wallet", 1, true)] - public string wallet { get; set; } + [SerializeField] private string contractAddress; - [Parameter("uint256", "amount", 2, false)] - public BigInteger amount { get; set; } -} + Erc20Contract _erc20Contract; -public class GetTxDataFromReceipt : MonoBehaviour -{ - - /// - /// Gets events data from a transaction, in this case the wallet and the amount in the event - /// - public async void EventTxData() + public async void Start() { - string eventContract = "0x9832B82746a4316E9E3A5e6c7ea02451bdAC4546"; - var amount = 1; - object[] args = - { - amount - }; - var contract = Web3Accessor.Web3.ContractBuilder.Build(ABI.ArrayTotal, eventContract); - var data = await contract.SendWithReceipt("addTotal", args); - // Quick pause to deal with chain congestion - await new WaitForSeconds(2); - // Event data from receipt - var logs = data.receipt.Logs.Select(jToken => JsonConvert.DeserializeObject(jToken.ToString())); - var eventAbi = EventExtensions.GetEventABI(); - var eventLogs = logs - .Select(log => eventAbi.DecodeEvent(log)) - .Where(l => l != null); - - if (!eventLogs.Any()) - { - Debug.Log("No event data"); - } - else - { - Debug.Log("Event data found"); - foreach (var eventLog in eventLogs) - { - var eventData = eventLog.Event; - Debug.Log($"Wallet from event data: {eventData.wallet}"); - Debug.Log($"Amount from event data: {eventData.amount}"); - } - } - } -} -``` + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); -### Registered Contract -Allows a contract to be registered for easy calling. + _erc20Contract = await Web3Unity.Instance.BuildContract(contractAddress); + } -``` csharp -using UnityEngine; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.UnityPackage; -using Scripts.EVM.Token; + public async Task BalanceOf(string account) + { + //Using the non-generic one since that way you can process the data a bit more granually + var response = await _erc20.OriginalContract.Call("balanceOf", new object[] + { + account + }); -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ + return (BigInteger)response[0]; + } -/// -/// Allows a contract to be registered for easy calling -/// -public class RegisteredContract : MonoBehaviour -{ - // Variables - private string registeredContractName = "CsTestErc20"; - // Function - public async void RegisteredContractCall() + public async void OnDestroy() { - var balance = await Evm.UseRegisteredContract(Web3Accessor.Web3, registeredContractName, EthMethods.BalanceOf); - SampleOutputUtil.PrintResult(balance.ToString(), nameof(Evm), nameof(Evm.UseRegisteredContract)); - // You can make additional changes after this line + await _erc20Contract.DisposeAsync(); } + + } ``` -### ECDSA Sign Transaction -Signs a transaction with an ECDSA key +But if you still prefer something similar to the old EVM.ContractCall/EVM.ContractSend, those methods are now part of the Web3Unity class. -``` csharp -using UnityEngine; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Signs a transaction with an ECDSA key. -/// -public class EcdsaSignTransaction : MonoBehaviour +```csharp +public class CustomContractSample : MonoBehaviour { - // Variables - // Variables - private string ecdsaKey = "0x78dae1a22c7507a4ed30c06172e7614eb168d3546c13856340771e63ad3c0081"; - private string chainId = "11155111"; - private string transactionHash = "0x123456789"; - - // Function - public void EcdsaSignTransactionCall() - { - var result = Evm.EcdsaSignTransaction(ecdsaKey, transactionHash, chainId); - SampleOutputUtil.PrintResult(result, nameof(Evm), nameof(Evm.EcdsaSignTransaction)); - // You can make additional changes after this line - } -} -``` - -### ECDSA Get Address -Gets the public address the private key belongs to. + [SerializeField] private string contractAddress; + [SerializeField] private string contractAbi; + [SerializeField] private string contractMethod; -``` csharp -using UnityEngine; -using Scripts.EVM.Token; + public async void Start() + { + if(Web3Unity.Web3 == null) + await Web3Unity.Instance.Initialize(false); -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ + //Used for writing to the chain + await Web3Unity.Instance.ContractSend(contractMethod, contractAbi, contractAddress); -/// -/// Gets the public address the private key belongs to. -/// -public class EcdsaGetAddress : MonoBehaviour -{ - // Variables - private string ecdsaKey = "0x78dae1a22c7507a4ed30c06172e7614eb168d3546c13856340771e63ad3c0081"; - - // Function - public void EcdsaGetAddressCall() - { - var result = Evm.EcdsaGetAddress(ecdsaKey); - SampleOutputUtil.PrintResult(result, nameof(Evm), nameof(Evm.EcdsaGetAddress)); - // You can make additional changes after this line + + //Used for reading from the chain + await Web3Unity.Instance.ContractRead(contractMethod, contractAbi, contractAddress); } + } ``` -### ECDSA Sign Message -Signs a message using a private key. +## IPFS Upload +In order to upload your files to IPFS, you will need to obtain your storage API secret and bucket id from ChainSafe's storage [here](https://app.storage.chainsafe.io/). ``` csharp -using UnityEngine; -using Scripts.EVM.Token; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - -/// -/// Signs a message using a private key -/// -public class EcdsaSignMessage : MonoBehaviour +public class IpfsSample : MonoBehaviour, ISample { - // Variables - private string ecdsaKey = "0x78dae1a22c7507a4ed30c06172e7614eb168d3546c13856340771e63ad3c0081"; - private string message = "secretmessage"; - - // Function - public void EcdsaSignMessageCall() - { - var result = Evm.EcdsaSignMessage(ecdsaKey, message); - SampleOutputUtil.PrintResult(result, nameof(Evm), nameof(Evm.EcdsaSignMessage)); - // You can make additional changes after this line - } -} -``` + #region Fields -### Multicall -Makes a multicall. + [field: SerializeField] public string Title { get; private set; } -``` csharp -using UnityEngine; -using System.Numerics; -using ChainSafe.Gaming.Evm.Contracts.BuiltIn; -using ChainSafe.Gaming.MultiCall; -using ChainSafe.Gaming.UnityPackage; -using Nethereum.Contracts.QueryHandlers.MultiCall; -using Scripts.EVM.Token; + [field: SerializeField, TextArea] public string Description { get; private set; } -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ + public Type[] DependentServiceTypes => Array.Empty(); -/// -/// Makes a multicall -/// -public class MulticallSample : MonoBehaviour -{ - // Function - public void MultiSampleCall() - { - var erc20Contract = Web3Accessor.Web3.ContractBuilder.Build(ABI.Erc20, ChainSafeContracts.Erc20); - var erc20BalanceOfCalldata = erc20Contract.Calldata(EthMethods.BalanceOf, new object[] - { - Erc20Account - }); + [Header("IPFS VALUES")] + [SerializeField] private string apiSecretKey = "Fill In Your API Secret Key From Storage"; + [SerializeField] private string bucketId = "Fill In Your Bucket ID From Storage"; + [SerializeField] private string fileNameImage = "Logo.png"; + [SerializeField] private string fileNameMetaData = "MetaData.json"; + [SerializeField] private string nftName = "Name of the NFT"; + [SerializeField] private string description = "An NFT description"; + [SerializeField] private string externalUrl = "The URL that appears below your assets image"; + [SerializeField] private List display_types = new List { "Stamina", "Boost Number" }; + [SerializeField] private List trait_types = new List { "Health", "Thunder Power" }; + [SerializeField] private List values = new List { "5", "20" }; + [Header("Required for image only upload")] + [SerializeField] private string imageCID = "Enter your image CID from storage or upload call"; - var erc20TotalSupplyCalldata = erc20Contract.Calldata(EthMethods.TotalSupply, new object[] - { - }); + #endregion + + #region Methods - var calls = new[] + /// + /// Uploads an image selected by the user to IPFS + /// + public async Task IPFSUploadImage() + { + var uploadRequest = new IPFSUploadRequestModel { - new Call3Value() - { - Target = ChainSafeContracts.Erc20, - AllowFailure = true, - CallData = erc20BalanceOfCalldata.HexToByteArray(), - }, - new Call3Value() - { - Target = ChainSafeContracts.Erc20, - AllowFailure = true, - CallData = erc20TotalSupplyCalldata.HexToByteArray(), - } + ApiKey = apiSecretKey, + BucketId = bucketId, + FileNameImage = fileNameImage }; + var cid = await IPFS.UploadImage(uploadRequest); + return $"Image uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"; + } - var multicallResultResponse = await Web3Accessor.Web3.MultiCall().MultiCallAsync(calls); - - Debug.Log(multicallResultResponse); - - if (multicallResultResponse[0] != null && multicallResultResponse[0].Success) + /// + /// Uploads metadata to IPFS + /// + public async Task IPFSUploadMetadata() + { + var uploadRequest = new IPFSUploadRequestModel { - var decodedBalanceOf = erc20Contract.Decode(EthMethods.BalanceOf, multicallResultResponse[0].ReturnData.ToHex()); - Debug.Log($"decodedBalanceOf {((BigInteger)decodedBalanceOf[0]).ToString()}"); - } + ApiKey = apiSecretKey, + BucketId = bucketId, + Image = imageCID, + FileNameMetaData = fileNameMetaData, + Name = nftName, + Description = description, + External_url = externalUrl, + attributes = IPFS.CreateAttributesList(display_types, trait_types, values) + }; + var cid = await IPFS.UploadMetaData(uploadRequest); + return $"Metadata uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"; + } - if (multicallResultResponse[1] != null && multicallResultResponse[1].Success) + /// + /// Uploads an image selected by the user including metadata to IPFS + /// + public async Task IPFSUploadImageAndMetadata() + { + var uploadRequest = new IPFSUploadRequestModel { - var decodedTotalSupply = erc20Contract.Decode(EthMethods.TotalSupply, multicallResultResponse[1].ReturnData.ToHex()); - Debug.Log($"decodedTotalSupply {((BigInteger)decodedTotalSupply[0]).ToString()}"); - } - // You can make additional changes after this line + ApiKey = apiSecretKey, + BucketId = bucketId, + FileNameImage = fileNameImage, + FileNameMetaData = fileNameMetaData, + Name = name, + Description = description, + External_url = externalUrl, + attributes = IPFS.CreateAttributesList(display_types, trait_types, values) + }; + var cid = await IPFS.UploadImageAndMetadata(uploadRequest); + return $"Image & metadata uploaded to https://ipfs.chainsafe.io/ipfs/{cid}"; } + + #endregion } + ``` ## Gelato Sample Scripts @@ -1769,15 +217,53 @@ The scripts function should be called by a method of your choosing - button, fun /// public class GelatoCallWithSyncFee : MonoBehaviour { - public async void CallWithSyncFee() - { - gelato = new GelatoSample(Web3Accessor.Web3); - var result = await gelato.CallWithSyncFee(); - SampleOutputUtil.PrintResult( - $"Task complete. Final status of {result.TaskId}: {result.Status.TaskState}. " + - $"Transaction hash: {result.Status.TransactionHash}", - nameof(GelatoSample), nameof(GelatoSample.CallWithSyncFee)); - // You can make additional changes after this line + public async Task CallWithSyncFee() + { + const string vitalik = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; + const string target = "0xA045eb75e78f4988d42c3cd201365bDD5D76D406"; + const string feeToken = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + const string abi = "[{\"inputs\": [" + + "{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}," + + "{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}," + + "{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}" + + "]," + + "\"name\":\"sendToFriend\"," + + "\"outputs\":[]," + + "\"stateMutability\":\"nonpayable\"," + + "\"type\":\"function\"" + + "}]"; + var contract = _web3.ContractBuilder.Build(abi, target); + var data = contract.Calldata("sendToFriend", new object[] + { + feeToken, + vitalik, + new BigInteger(5 * 10E12), + }); + + var relayResponse = await _web3.Gelato().CallWithSyncFee(new CallWithSyncFeeRequest() + { + Data = data, + FeeToken = feeToken, + IsRelayContext = true, + Target = target, + }); + + while (true) + { + var status = await _web3.Gelato().GetTaskStatus(relayResponse.TaskId); + + switch (status.TaskState) + { + case TaskState.ExecSuccess: + case TaskState.ExecReverted: + case TaskState.Cancelled: + return $"Task complete. Final status of {relayResponse.TaskId}: {status.TaskState}. " + + $"Transaction hash: {status.TransactionHash}"; + default: + await WaitForSeconds(2); + continue; + } + } } } ``` @@ -1786,28 +272,49 @@ public class GelatoCallWithSyncFee : MonoBehaviour Allows sponsor calling to Gelato with sync fee for ERC2771. ``` csharp -using UnityEngine; -using System.Threading.Tasks; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - /// -/// Allows sponsor calling to Gelato with sync fee for ERC2771 +/// Gelato2771 with sync fee /// -public class GelatoCallWithSyncFeeErc2771 : MonoBehaviour +public async Task CallWithSyncFeeErc2771() { - public async void CallWithSyncFeeErc2771() + const string target = "0x5dD1100f23278e0e27972eacb4F1B81D97D071B7"; + const string feeToken = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + const string abi = "[{\"inputs\": []," + + "\"name\":\"increment\"," + + "\"outputs\":[]," + + "\"stateMutability\":\"nonpayable\"," + + "\"type\":\"function\"" + + "}]"; + var contract = _web3.ContractBuilder.Build(abi, target); + + var data = contract.Calldata("increment", new object[] { - gelato = new GelatoSample(Web3Accessor.Web3); - var result = await gelato.CallWithSyncFeeErc2771(); - SampleOutputUtil.PrintResult( - $"Task complete. Final status of {result.TaskId}: {result.Status.TaskState}. " + - $"Transaction hash: {result.Status.TransactionHash}", - nameof(GelatoSample), nameof(GelatoSample.CallWithSyncFeeErc2771)); - // You can make additional changes after this line + }); + + var relayResponse = await _web3.Gelato().CallWithSyncFeeErc2771(new CallWithSyncFeeErc2771Request() + { + Target = target, + Data = data, + FeeToken = feeToken, + IsRelayContext = true, + }); + + while (true) + { + var status = await _web3.Gelato().GetTaskStatus(relayResponse.TaskId); + + switch (status.TaskState) + { + case TaskState.ExecSuccess: + case TaskState.ExecReverted: + case TaskState.Cancelled: + return + $"Task complete. Final status of {status.TaskId}: {status.TaskState}. " + + $"Transaction hash: {status.TransactionHash}"; + default: + await WaitForSeconds(2); + continue; + } } } ``` @@ -1816,28 +323,45 @@ public class GelatoCallWithSyncFeeErc2771 : MonoBehaviour Allows sponsor calling to Gelato. ``` csharp -using UnityEngine; -using System.Threading.Tasks; -using ChainSafe.Gaming.UnityPackage; - -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ - /// -/// Allows sponsor calling to Gelato +/// Gelato sponsor call /// -public class GelatoSponsorCall : MonoBehaviour +public async Task SponsorCall() { - public async void SponsorCall() + const string counterContract = "0x763D37aB388C5cdd2Fb0849d6275802F959fbF30"; + + const string abi = "[{\"inputs\": []," + + "\"name\":\"increment\"," + + "\"outputs\":[]," + + "\"stateMutability\":\"nonpayable\"," + + "\"type\":\"function\"" + + "}]"; + var contract = _web3.ContractBuilder.Build(abi, counterContract); + + var data = contract.Calldata("increment"); + + var relayResponse = await _web3.Gelato().SponsoredCall(new SponsoredCallRequest() + { + Target = counterContract, + Data = data, + }); + + while (true) { - gelato = new GelatoSample(Web3Accessor.Web3); - var result = await gelato.SponsorCall(); - SampleOutputUtil.PrintResult( - $"Task complete. Final status of {result.TaskId}: {result.Status.TaskState}. " + - $"Transaction hash: {result.Status.TransactionHash}", - nameof(GelatoSample), nameof(GelatoSample.SponsorCall)); - // You can make additional changes after this line + var status = await _web3.Gelato().GetTaskStatus(relayResponse.TaskId); + + switch (status.TaskState) + { + case TaskState.ExecSuccess: + case TaskState.ExecReverted: + case TaskState.Cancelled: + return + $"Task complete. Final status of {relayResponse.TaskId}: {status.TaskState}. " + + $"Transaction hash: {status.TransactionHash}"; + default: + await WaitForSeconds(2); + continue; + } } } ``` @@ -1846,28 +370,44 @@ public class GelatoSponsorCall : MonoBehaviour Allows sponsor calling to Gelato for ERC2771. ``` csharp -using UnityEngine; -using System.Threading.Tasks; -using ChainSafe.Gaming.UnityPackage; +public async Task SponsorCallErc2771() +{ + const string target = "0x00172f67db60E5fA346e599cdE675f0ca213b47b"; -/* This sample script should be copied & placed on the root of an object in a scene. -Change the class name, variables and add any additional changes at the end of the function. -The scripts function should be called by a method of your choosing - button, function etc */ + const string abi = "[{\"inputs\": []," + + "\"name\":\"increment\"," + + "\"outputs\":[]," + + "\"stateMutability\":\"nonpayable\"," + + "\"type\":\"function\"" + + "}]"; -/// -/// Allows sponsor calling to Gelato for ERC2771 -/// -public class GelatoSponsorCallErc2771 : MonoBehaviour -{ - public async void SponsorCallErc2771() + var contract = _web3.ContractBuilder.Build(abi, target); + + var data = contract.Calldata("increment"); + + var relayResponse = await _web3.Gelato().SponsoredCallErc2771(new SponsoredCallErc2771Request() + { + Target = target, + Data = data, + User = _web3.Signer.PublicAddress, + }); + + while (true) { - gelato = new GelatoSample(Web3Accessor.Web3); - var result = await gelato.SponsorCallErc2771(); - SampleOutputUtil.PrintResult( - $"Task complete. Final status of {result.TaskId}: {result.Status.TaskState}. " + - $"Transaction hash: {result.Status.TransactionHash}", - nameof(GelatoSample), nameof(GelatoSample.SponsorCallErc2771)); - // You can make additional changes after this line + var status = await _web3.Gelato().GetTaskStatus(relayResponse.TaskId); + + switch (status.TaskState) + { + case TaskState.ExecSuccess: + case TaskState.ExecReverted: + case TaskState.Cancelled: + return + $"Task complete. Final status of {status.TaskId}: {status.TaskState}. " + + $"Transaction hash: {status.TransactionHash}"; + default: + await WaitForSeconds(2); + continue; + } } } ``` \ No newline at end of file diff --git a/docs/v2.6/assets/abi-csharp-contract/abi-csharp-filled.png b/docs/v2.6/assets/abi-csharp-contract/abi-csharp-filled.png new file mode 100644 index 0000000..bd66169 Binary files /dev/null and b/docs/v2.6/assets/abi-csharp-contract/abi-csharp-filled.png differ diff --git a/docs/v2.6/assets/abi-csharp-contract/abi-csharp-overview.png b/docs/v2.6/assets/abi-csharp-contract/abi-csharp-overview.png new file mode 100644 index 0000000..196ecdd Binary files /dev/null and b/docs/v2.6/assets/abi-csharp-contract/abi-csharp-overview.png differ diff --git a/docs/v2.6/assets/chain-switching/chain-settings.png b/docs/v2.6/assets/chain-switching/chain-settings.png new file mode 100644 index 0000000..7f2395f Binary files /dev/null and b/docs/v2.6/assets/chain-switching/chain-settings.png differ diff --git a/docs/v2.6/assets/getting-started/chain-settings.png b/docs/v2.6/assets/getting-started/chain-settings.png new file mode 100644 index 0000000..d0eeed5 Binary files /dev/null and b/docs/v2.6/assets/getting-started/chain-settings.png differ diff --git a/docs/v2.6/assets/getting-started/import-samples.png b/docs/v2.6/assets/getting-started/import-samples.png index 4f72753..0bedd08 100644 Binary files a/docs/v2.6/assets/getting-started/import-samples.png and b/docs/v2.6/assets/getting-started/import-samples.png differ diff --git a/docs/v2.6/assets/getting-started/project-settings.png b/docs/v2.6/assets/getting-started/project-settings.png index 1b53436..cf2d03f 100644 Binary files a/docs/v2.6/assets/getting-started/project-settings.png and b/docs/v2.6/assets/getting-started/project-settings.png differ diff --git a/docs/v2.6/assets/getting-started/web3unity-prefab.png b/docs/v2.6/assets/getting-started/web3unity-prefab.png new file mode 100644 index 0000000..57b7b9e Binary files /dev/null and b/docs/v2.6/assets/getting-started/web3unity-prefab.png differ diff --git a/docs/v2.6/assets/login-process/connect-to-wallet-2.png b/docs/v2.6/assets/login-process/connect-to-wallet-2.png new file mode 100644 index 0000000..750e7c5 Binary files /dev/null and b/docs/v2.6/assets/login-process/connect-to-wallet-2.png differ diff --git a/docs/v2.6/assets/login-process/connect-to-wallet.png b/docs/v2.6/assets/login-process/connect-to-wallet.png new file mode 100644 index 0000000..9fff55e Binary files /dev/null and b/docs/v2.6/assets/login-process/connect-to-wallet.png differ diff --git a/docs/v2.6/assets/login-process/connection-handler-1.png b/docs/v2.6/assets/login-process/connection-handler-1.png new file mode 100644 index 0000000..315f03f Binary files /dev/null and b/docs/v2.6/assets/login-process/connection-handler-1.png differ diff --git a/docs/v2.6/assets/login-process/connection-handler-2.png b/docs/v2.6/assets/login-process/connection-handler-2.png new file mode 100644 index 0000000..066ceb1 Binary files /dev/null and b/docs/v2.6/assets/login-process/connection-handler-2.png differ diff --git a/docs/v2.6/assets/service-adapters/service-adapters.png b/docs/v2.6/assets/service-adapters/service-adapters.png new file mode 100644 index 0000000..af4b729 Binary files /dev/null and b/docs/v2.6/assets/service-adapters/service-adapters.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-create-project-name.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-create-project-name.png index 9c1a13f..e947635 100644 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-create-project-name.png and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-create-project-name.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-get-started-button.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-get-started-button.png index 49bb2b8..dd65133 100644 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-get-started-button.png and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-get-started-button.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-https-endpoints.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-https-endpoints.png index f54116f..67d5981 100644 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-https-endpoints.png and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-https-endpoints.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-join-network.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-join-network.png index ed625f5..0f859a6 100644 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-join-network.png and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-join-network.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-naming-node.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-naming-node.png deleted file mode 100644 index c1cbf4d..0000000 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-naming-node.png and /dev/null differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-deployment.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-deployment.png new file mode 100644 index 0000000..fca3acb Binary files /dev/null and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-deployment.png differ diff --git a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-status.png b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-status.png index dc70a60..e7d52f7 100644 Binary files a/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-status.png and b/docs/v2.6/assets/setting-up-an-rpc-node/chainstack-node-status.png differ diff --git a/docs/v2.6/assets/wallets/overview/connection-handler.png b/docs/v2.6/assets/wallets/overview/connection-handler.png new file mode 100644 index 0000000..6e6b0ba Binary files /dev/null and b/docs/v2.6/assets/wallets/overview/connection-handler.png differ diff --git a/docs/v2.6/assets/wallets/reown/reown-app-kit.png b/docs/v2.6/assets/wallets/reown/reown-app-kit.png new file mode 100644 index 0000000..6e06d40 Binary files /dev/null and b/docs/v2.6/assets/wallets/reown/reown-app-kit.png differ diff --git a/docs/v2.6/assets/wallets/reown/reown-connect-info.png b/docs/v2.6/assets/wallets/reown/reown-connect-info.png new file mode 100644 index 0000000..8aae4ee Binary files /dev/null and b/docs/v2.6/assets/wallets/reown/reown-connect-info.png differ diff --git a/docs/v2.6/assets/wallets/reown/reown-dash.png b/docs/v2.6/assets/wallets/reown/reown-dash.png new file mode 100644 index 0000000..d51650a Binary files /dev/null and b/docs/v2.6/assets/wallets/reown/reown-dash.png differ diff --git a/docs/v2.6/assets/wallets/reown/reown-new-project.png b/docs/v2.6/assets/wallets/reown/reown-new-project.png new file mode 100644 index 0000000..ecba194 Binary files /dev/null and b/docs/v2.6/assets/wallets/reown/reown-new-project.png differ diff --git a/docs/v2.6/assets/wallets/reown/reown-project-info.png b/docs/v2.6/assets/wallets/reown/reown-project-info.png new file mode 100644 index 0000000..afa57f1 Binary files /dev/null and b/docs/v2.6/assets/wallets/reown/reown-project-info.png differ diff --git a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-dash.png b/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-dash.png deleted file mode 100644 index 6fdbf6f..0000000 Binary files a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-dash.png and /dev/null differ diff --git a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-info.png b/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-info.png deleted file mode 100644 index 6b5d59f..0000000 Binary files a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-info.png and /dev/null differ diff --git a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-login-logic.png b/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-login-logic.png deleted file mode 100644 index d1e27d8..0000000 Binary files a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-login-logic.png and /dev/null differ diff --git a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-new-project.png b/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-new-project.png deleted file mode 100644 index 102c22d..0000000 Binary files a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-new-project.png and /dev/null differ diff --git a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-project-id.png b/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-project-id.png deleted file mode 100644 index 37809b3..0000000 Binary files a/docs/v2.6/assets/wallets/wallet-connect/wallet-connect-project-id.png and /dev/null differ diff --git a/docs/v2.6/assets/wallets/web3auth/web3auth-config.png b/docs/v2.6/assets/wallets/web3auth/web3auth-config.png new file mode 100644 index 0000000..45c2b71 Binary files /dev/null and b/docs/v2.6/assets/wallets/web3auth/web3auth-config.png differ diff --git a/docs/v2.6/assets/wallets/web3auth/web3auth-wallet.png b/docs/v2.6/assets/wallets/web3auth/web3auth-wallet.png new file mode 100644 index 0000000..3e9d0e7 Binary files /dev/null and b/docs/v2.6/assets/wallets/web3auth/web3auth-wallet.png differ diff --git a/docs/v2.6/assets/wallets/web3auth/web3authgui-config.png b/docs/v2.6/assets/wallets/web3auth/web3authgui-config.png new file mode 100644 index 0000000..8c98ed6 Binary files /dev/null and b/docs/v2.6/assets/wallets/web3auth/web3authgui-config.png differ diff --git a/sidebars.js b/sidebars.js index 4d4a03f..6e749ab 100644 --- a/sidebars.js +++ b/sidebars.js @@ -3,65 +3,66 @@ module.exports = { docs: [ 'chainsafe-gaming', { - "type": "category", - "label": "SDK Documentation", - "collapsed": false, - "items": [ - "v2.6/getting-started", + type: 'category', + label: 'SDK Documentation', + collapsed: false, + items: [ + 'v2.6/getting-started', { type: 'category', label: 'Choose Your Wallet', items: [ - "v2.6/choose-your-wallet", - "v2.6/metamask", - "v2.6/wallet-connect", - "v2.6/web3auth", - "v2.6/hyperplay" - ] + 'v2.6/choose-your-wallet', + 'v2.6/metamask', + 'v2.6/reown', + 'v2.6/web3auth', + 'v2.6/hyperplay', + ], }, - "v2.6/setting-up-an-rpc-node", - "v2.6/login-process", - "v2.6/sample-scripts-and-chain-interactions", + 'v2.6/setting-up-an-rpc-node', + 'v2.6/login-process', + 'v2.6/abi-to-csharp-converter', + 'v2.6/chain-switching', + 'v2.6/blockchain-events', + 'v2.6/mud', + 'v2.6/sample-scripts-and-chain-interactions', { type: 'category', label: 'Packages & Extensions', items: [ - "v2.6/gasless-transactions-using-gelato", - "v2.6/ramp", - "v2.6/lootboxes", - "v2.6/marketplace", - "v2.6/extending-the-sdk" - ] + 'v2.6/service-adapters', + 'v2.6/gasless-transactions-using-gelato', + 'v2.6/ramp', + 'v2.6/lootboxes', + 'v2.6/extending-the-sdk', + ], }, { type: 'category', label: 'Game Examples', - items: [ - "v2.6/block-racers-game", - "v2.6/block-blasterz-game" - ] + items: ['v2.6/block-racers-game', 'v2.6/block-blasterz-game'], }, - "v2.6/faq" - ] + 'v2.6/faq', + ], }, { type: 'category', label: 'NFT Launchpad', items: [ - "nft_launchpad/introduction", - "nft_launchpad/details", - "nft_launchpad/tutorial", - "token-api/docs/tokenapi", + 'nft_launchpad/introduction', + 'nft_launchpad/details', + 'nft_launchpad/tutorial', + 'token-api/docs/tokenapi', ], }, { type: 'category', label: 'Marketplace', items: [ - "nft_marketplace/introduction", - "nft_marketplace/tutorial", - "marketplace-api/docs/marketplaceapi", + 'nft_marketplace/introduction', + 'nft_marketplace/tutorial', + 'marketplace-api/docs/marketplaceapi', ], }, ], -}; +}