diff --git a/docs/unity.md b/docs/unity.md index b4c964b0d..4d9f0180f 100644 --- a/docs/unity.md +++ b/docs/unity.md @@ -2,26 +2,38 @@ title: Tezos Unity SDK authors: Tim McMackin last_update: - date: 11 January 2024 + date: 25 November 2024 --- -The Tezos Unity SDK provides tools that let you access user wallets and Tezos in games and other Unity projects. -You can use Tezos via the SDK to: +The Tezos Unity SDK provides tools that let you access user wallets and blockchains in games and other Unity projects. +You can use the SDK to: -- Use a player's Tezos account as their account for a game and their wallet as their way of logging in to the game -- Accept payments from players in tez -- Use Tezos to create game assets, store player inventories, and transfer assets between players -- Verify that users own specific game assets and allow them to sell or share them to other players -- Use Tezos smart contracts as backend logic for games +- Use a player's account as their account for a game and their wallet as their way of logging in to the game +- Accept payments from players in tez (XTZ), the primary cryptocurrency of the Tezos and Etherlink blockchains +- Use blockchains to create game assets, store player inventories, and transfer assets between players +- Verify that users own specific game assets and allow them to transfer them to other players +- Use smart contracts as backend logic for games + +The SDK can connect to and use these blockchains: + +- [Tezos](https://tezos.com) +- [Etherlink](https://etherlink.com) ## Installation and use For a walkthrough of installing and using the SDK in an existing Unity project, see [Quickstart](/unity/quickstart). +## Upgrading from version 3 + +Version 4.0 has breaking changes. +To upgrade, see [Upgrading the Unity SDK](/unity/upgrading). + + ## Sample game @@ -38,9 +50,13 @@ The Tezos SDK uses modified versions of the following libraries for communicatio - **Airgap Beacon SDK**: Interacts with Tezos wallets through the Beacon standard for iOS, Android, and WebGL platforms. - **Netezos**: Interacts with Tezos wallets through the Beacon standard for Windows, Linux, and MacOS platforms. Also prepares parameters for smart contract calls and interprets complex data returned by the ReadView method. +- **WalletConnect**: Interacts with EVM wallets with the WalletConnect protocol. +To use WalletConnect wallets, you must install the [Tezos WalletConnect Unity SDK](https://github.com/trilitech/tezos-wallet-connect-unity-sdk). The SDK also uses the [Newtonsoft JSON Unity Package](https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.2/manual/index.html). ## Supported Platforms The SDK supports Windows, Linux, MacOS, iOS, Android, and WebGL platforms. + +For information about the kinds of wallets the SDK supports, see [Connecting accounts](/unity/connecting-accounts). diff --git a/docs/unity/calling-contracts.md b/docs/unity/calling-contracts.md new file mode 100644 index 000000000..efc8d2f31 --- /dev/null +++ b/docs/unity/calling-contracts.md @@ -0,0 +1,441 @@ +--- +title: Calling contracts with the Unity SDK +sidebar_label: Calling contracts +authors: Tim McMackin +last_update: + date: 8 January 2025 +--- + +Smart contracts are backend programs that run on blockchains. +Smart contracts can do many tasks, but for gaming they have two main purposes: + +- They handle tokens, which are digital assets stored on the blockchain +- They provide backend logic that users can trust because it cannot change + +For more information about smart contracts on Tezos, see [Smart contracts](/smart-contracts). + +The Unity SDK can call any deployed Tezos or Etherlink contract just like any other Tezos or EVM client can. + +- To call a Tezos smart contract, the application must be connected to a Beacon or social wallet +- To call an Etherlink smart contract, the application must be connected to a WalletConnect contract + +## Calling Tezos contracts + +Smart contracts have one or more [entrypoints](/smart-contracts/entrypoints), which are the different ways that it can be called, similar to a method or function in programming languages or an endpoint in an API. +Therefore, to call a Tezos smart contract, you need: + +- Its address, which starts with `KT1` +- The entrypoint to call +- The parameter to pass to the entrypoint, which must be in the format that the entrypoint expects +- An amount of tez tokens to send with the transaction, which can be zero or more + +To call a contract, make sure that you are connected to a Beacon wallet. +Then create an `OperationRequest` object with that information and pass it to the `TezosAPI.RequestOperation()` method. +To get the result of the operation, you can await the return value of the `TezosAPI.RequestOperation()` method or use the `TezosAPI.OperationResulted` event. + +For example, this code calls a contract and passes the parameter `5` to its `increment` entrypoint. +When the transaction completes successfully, it logs the hash of the transaction. +You can use this hash to look up information about the transaction in a [block explorer](/developing/information/block-explorers). + +```csharp +private async void Awake() +{ + await TezosAPI.WaitUntilSDKInitialized(); + + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + _requestOperationButton.onClick.AddListener(OnRequestOperationClicked); + + TezosAPI.OperationResulted += OperationResulted; +} + +private async void OnRequestOperationClicked() +{ + // Verify that the app is connected to an EVM wallet via WalletConnect + WalletProviderData walletProviderData = TezosAPI.GetWalletConnectionData(); + if (walletProviderData.WalletType != WalletType.BEACON && !TezosAPI.IsSocialLoggedIn()) { + Debug.LogError("Connect to a Beacon or social wallet first."); + return; + } + + try + { + var request = new OperationRequest + { + // Contract to call + Destination = "KT1R2LTg3mQoLvHtUjo2xSi7RMBUJ1sJkDiD", + // Entrypoint to call + EntryPoint = "increment", + // Parameter to pass, as a Michelson expression + Arg = new MichelineInt(5).ToJson(), + // Amount of tez to send with the transaction + Amount = "0", + }; + var response = await TezosAPI.RequestOperation(request); + Debug.Log("Transaction hash: " + response.TransactionHash); + } + catch (Exception e) when (e is WalletOperationRejected or SocialOperationFailed) + { + Debug.LogError($"Operation failed: {e.Message}"); + } + catch (Exception e) + { + Debug.LogError($"Unexpected error during operation: {e.Message}"); + } +} + +private void OperationResulted(OperationResponse operationResponse) +{ + Debug.Log("Transaction hash: " + operationResponse.TransactionHash); +} +``` + +### Encoding parameters + +Tezos entrypoint parameters must be in [Micheline](https://tezos.gitlab.io/shell/micheline.html) JSON format, which is the format that the Michelson language uses for values. +You can use the [Netezos](https://netezos.dev/) SDK to format Micheline parameters or construct them as JSON strings. + +#### Encoding parameters with the Netezos Micheline SDK + +Micheline primitives include: + +- Integers, as in `new MichelineInt(1)` +- Strings, as in `new MichelineString("Hello")` +- Bytes, as in `new MichelineBytes(bytes")` + +As described in [Complex data types](/smart-contracts/data-types/complex-data-types), Micheline values are organized as a series of nested pairs in tree and comb formats. +For example, if an entrypoint accepts an integer, a string, and a series of bytes as a nested pair, you can format the parameter like this: + +```csharp +string myStringToBytes = "Hello!"; +var bytes = new byte[myStringToBytes.Length]; + +for (var i = 0; i < myStringToBytes.Length; i++) +{ + bytes[i] = (byte)myStringToBytes[i]; +} + +var parameter = new MichelinePrim +{ + Prim = PrimType.Pair, + Args = new List + { + new MichelineInt(1), + new MichelineString("Hello"), + new MichelineBytes(bytes) + } +}.ToJson(); + +var request = new OperationRequest +{ + Destination = "KT1PB9rp17qfL6RQR9ZUsKMm3NvbSoTopnwY", + EntryPoint = "intStringBytes", + Arg = parameter, + Amount = "0", +}; +var response = await TezosAPI.RequestOperation(request); +``` + +#### Encoding parameters as JSON strings + +Because the `Arg` field of the `OperationRequest` object accepts a JSON string, you can also use a raw Micheline-formatted JSON string. +For example, the `MichelinePrim` object in the previous example looks like this as a string: + +```json +{ + "prim": "Pair", + "args": [ + { + "int": "1" + }, + { + "string": "Hello" + }, + { + "bytes": "48656c6c6f21" + } + ] +} +``` + +Therefore, you can create a string literal with this JSON, escaping characters as necessary, and use it in the `OperationRequest` object, as in this example: + +```csharp +var jsonString = "{\"prim\":\"Pair\",\"args\":[{\"int\":\"1\"},{\"string\":\"Hello\"},{\"bytes\":\"48656c6c6f21\"}]}"; + +var request = new OperationRequest +{ + Destination = "KT1PB9rp17qfL6RQR9ZUsKMm3NvbSoTopnwY", + EntryPoint = "intStringBytes", + Arg = jsonString, + Amount = "0", +}; +``` + +Block explorers can help you format parameters. +For example, assume an entrypoint that accepts a parameter that consists of a string followed by any number of pairs of an integer and a string. +If you fill in values for this parameter on the **Interact** tab of [Better Call Dev](https://better-call.dev) and click **Execute > Raw JSON**, it shows this Micheline value in JSON format: + +```json +{ + "prim": "Pair", + "args": [ + { + "string": "My string" + }, + [ + { + "prim": "Pair", + "args": [ + { + "int": "5" + }, + { + "string": "String one" + } + ] + }, + { + "prim": "Pair", + "args": [ + { + "int": "9" + }, + { + "string": "String two" + } + ] + }, + { + "prim": "Pair", + "args": [ + { + "int": "12" + }, + { + "string": "String three" + } + ] + } + ] + ] +} +``` + +You can convert this JSON to a string and use it in the parameter instead of constructing the JSON with Netezos objects. + +## Calling Tezos views + +To call a [view](/smart-contracts/views), pass the address of the contract, the name of the view, and the Michelson-encoded parameter to the `TezosAPI.ReadView()` method. +You must set the return type on the `TezosAPI.ReadView()` method, as in this example for a view that returns a string: + +```csharp +var result = await TezosAPI.ReadView("KT1K46vZTMEe8bnacFvFQfgHtNDKniEauRMJ", "simple", "\"String value\""); +Debug.Log("View response: " + result); +``` + +If the return type is more complicated than a single primitive, you must create a type to represent the return type. +For example, the FA2 contract `KT1HP6uMwf829cDgwynZJ4rDvjLCZmfYjja1` has a view named `get_balance_of` that returns information about token owners. +Block explorers such as [tzkt.io](https://tzkt.io) show the parameter and return types for this view in JSON and Michelson format: + +Parameter and return types for the view + +The equivalent C# types look like these examples: + +```csharp +private class ParameterType +{ + public string owner; + public int token_id; +} + +private class ResponseType +{ + public Request request { get; set; } + public string balance { get; set; } +} + +public class Request +{ + public string owner { get; set; } + public string token_id { get; set; } +} +``` + +This example shows how to use these types to call the view and receive the response: + +```csharp +var parameter = new List +{ + new() + { + owner = "tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx", + token_id = 0 + }, + new() + { + owner = "tz1hQKqRPHmxET8du3fNACGyCG8kZRsXm2zD", + token_id = 0 + } + +}; + +var json = await TezosAPI.ReadView>( + "KT1HP6uMwf829cDgwynZJ4rDvjLCZmfYjja1", "get_balance_of", parameter +); + +foreach (var item in json) +{ + Debug.Log($"The account {item.request.owner} has {item.balance} tokens of type {item.request.token_id}"); +} +``` + +## Calling Etherlink contracts + +[Etherlink](https://www.etherlink.com/) is an Ethereum Virtual Machine-compatible layer that runs on top of Tezos and secures its state to Tezos via Smart Rollups. +The Unity SDK can send transactions to Etherlink, but not to any other EVM layer. +For more information about Etherlink, see the [Etherlink documentation](https://docs.etherlink.com/). + +Like Tezos contracts, Etherlink smart contracts have functions that clients can call. +To call an Etherlink smart contract, you need: + +- Its address +- The entrypoint to call +- The contract's application binary interface (ABI), which is a description of the contract's interface; you can get the ABI from the tool that deployed the contract or by compiling the source code of the contract in a tool such as the [Remix IDE](https://remix.ethereum.org/) +- The parameter to pass to the entrypoint +- An amount of XTZ to send with the transaction, which can be zero or more + +:::note + +Calls to Etherlink smart contracts do not run the `TezosAPI.OperationResulted` event. + +::: + +The Unity SDK uses the [Reown SDK](https://reown.com/), so before you can access Etherlink, you must set up Reown: + +1. At https://cloud.reown.com, create a Reown project and get its ID. + +1. In Unity, install the WalletConnect SDK from the Git URL `https://github.com/trilitech/tezos-wallet-connect-unity-sdk.git`. + +1. In the `Assets/Tezos/Resources/WalletConnectConfig.asset` object, in the **Project Id** field, add the ID of your Reown project and fill in the other fields with information including the name and URL of your application, as in this example: + + Setting the Reown project ID on the WalletConnectConfig object + +Now you can interact with Etherlink contracts with the Reown SDK. + +To call a contract, make sure that you are connected to a WalletConnect wallet. +Then use the `AppKit.Evm.WriteContractAsync()` method to call the contract. + +For example, this code calls a contract and passes the parameter `5` to its `set` entrypoint. +When the transaction completes successfully, it logs the hash of the transaction. +You can use this hash to look up information about the transaction in the [Etherlink Mainnet block explorer](https://explorer.etherlink.com/) or the [Etherlink Testnet block explorer](https://testnet.explorer.etherlink.com/). + + + +```csharp +using Reown.AppKit.Unity; + +public class MyScripts : MonoBehaviour +{ + + private async void Awake() + { + await TezosAPI.WaitUntilSDKInitialized(); + + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + _requestOperationButton.onClick.AddListener(OnRequestOperationClicked); + + TezosAPI.OperationResulted += OperationResulted; + } + + private async void OnRequestOperationClicked() + { + // Verify that the app is connected to an EVM wallet via WalletConnect + WalletProviderData walletProviderData = TezosAPI.GetWalletConnectionData(); + if (walletProviderData.WalletType != WalletType.WALLETCONNECT) { + Debug.LogError("Connect to a WalletConnect wallet first."); + return; + } + + try + { + string contractAddress = "0xfac1791E9db153ef693c68d142Cf11135b8270B9"; + string ABI = "[ { \"inputs\": [], \"name\": \"get\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"x\", \"type\": \"uint256\" } ], \"name\": \"set\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; + string entrypoint = "set"; + + var result = await AppKit.Evm.WriteContractAsync(contractAddress, ABI, entrypoint, "5"); + + Debug.Log("Result: " + result); + } + catch (Exception e) + { + Debug.LogError($"Unexpected error during operation: {e.Message}"); + } + } + + private void OperationResulted(OperationResponse operationResponse) + { + Debug.Log("Transaction hash: " + operationResponse.TransactionHash); + } + +} +``` + +The Tezos Unity SDK supports these Reown SDK methods, but only for calls to Etherlink, not any other EVM chain: + +- `AppKit.Evm.ReadContractAsync()` +- `AppKit.Evm.WriteContractAsync()` +- `AppKit.Evm.SendTransactionAsync()` +- `AppKit.Evm.SendRawTransactionAsync()` + +For more information about using the Reown SDK, see https://docs.reown.com/appkit/unity/core/usage. + +## Calling Etherlink views + +Calling an Etherlink view is similar to calling an Etherlink entrypoint. +The main difference is that you use the `AppKit.Evm.ReadContractAsync()` method and that you must set the return type to the appropriate Solidity type that the view returns. +This example calls a view that returns a `unit` integer type: + +```csharp +using Reown.AppKit.Unity; + +public class MyScripts : MonoBehaviour +{ + + private async void Awake() + { + await TezosAPI.WaitUntilSDKInitialized(); + + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + _callViewButton.onClick.AddListener(OnCallViewClicked); + } + + private async void OnCallViewClicked() + { + // Verify that the app is connected to an EVM wallet via WalletConnect + WalletProviderData walletProviderData = TezosAPI.GetWalletConnectionData(); + if (walletProviderData.WalletType != WalletType.WALLETCONNECT) { + Debug.LogError("Connect to a WalletConnect wallet first."); + return; + } + + try + { + string contractAddress = "0xfac1791E9db153ef693c68d142Cf11135b8270B9"; + string ABI = "[ { \"inputs\": [], \"name\": \"get\", \"outputs\": [ { \"internalType\": \"uint256\", \"name\": \"\", \"type\": \"uint256\" } ], \"stateMutability\": \"view\", \"type\": \"function\" }, { \"inputs\": [ { \"internalType\": \"uint256\", \"name\": \"x\", \"type\": \"uint256\" } ], \"name\": \"set\", \"outputs\": [], \"stateMutability\": \"nonpayable\", \"type\": \"function\" } ]"; + string entrypoint = "get"; + + var result = await AppKit.Evm.ReadContractAsync(contractAddress, ABI, entrypoint); + + Debug.Log("Result: " + result); + } + catch (Exception e) + { + Debug.LogError($"Unexpected error during operation: {e.Message}"); + } + } + +} +``` diff --git a/docs/unity/connecting-accounts.md b/docs/unity/connecting-accounts.md index 6b7513643..2fbda2610 100644 --- a/docs/unity/connecting-accounts.md +++ b/docs/unity/connecting-accounts.md @@ -2,17 +2,16 @@ title: Connecting accounts authors: Tim McMackin last_update: - date: 14 May 2024 + date: 25 November 2024 --- -Connecting to a user's wallet is a prerequisite to working with Tezos in any application. -Accessing the wallet allows your project to see the tokens in it and to prompt the user to submit transactions, but it does not give your project direct control over the wallet. +Connecting to a user's wallet allows your application to see the tokens in it and to prompt the user to submit transactions, but it does not give your application direct control over the wallet. Users still confirm or reject all transactions in their wallet application, so you must handle both of these use cases. Using a wallet application in this way saves you from having to implement payment processing and security in your application. Game developers can also use the wallet and its account as a unique account identifier and as the user's inventory. -For an example of connecting to wallets, see the [WalletConnection tutorial scene](/unity/scenes#wallet-connection-scene). + For more information about Tezos wallets, see [Installing and funding a wallet](/developing/wallet-setup). @@ -23,11 +22,6 @@ For example, don't force the user to connect their wallet as soon as the applica Instead, let them see the application first. Also, provide a prominent disconnect button to allow users to disconnect one account and connect a different one. -## The `TezosAuthenticator` prefab - -The `TezosAuthenticator` prefab provides the tools that you need to connect to user's Tezos wallets in a Unity project. -You can copy the `TezosAuthenticator` and `TezosManager` prefabs to your scene, and the `TezosAuthenticator` prefab automatically adds features that connect to users' wallets. - ## Connection methods This table shows the ways that the SDK can connect to wallets and which platforms they are appropriate for: @@ -38,45 +32,288 @@ QR code | Users scan a QR code with a wallet app | Yes | No | Yes Deep link | The application opens the user's wallet app directly | Yes | Yes | No Social wallets | The application opens the user's Kukai web-based wallet | Yes | No | No -Regardless of the connection method, the Tezos Unity SDK runs the `WalletConnected` or `WalletConnectionFailed` event, as appropriate. -For more information about events, see the [Unity SDK EventManager object](/unity/reference/EventManager). +When wallets connect or disconnect, the SDK runs the `WalletConnected` or `WalletDisconnect` events for non-social wallets and the `SocialLoggedIn` and `SocialLoggedOut` events for social wallets. - + + +## Wallet types + +The SDK supports three types of wallets: + +- Wallets that use the Tezos blockchain and connect to applications through the Beacon protocol, such as Temple +- Wallets that use the Tezos blockchain and connect to a federated identity login through [Kukai](https://wallet.kukai.app) +- Wallets that use the Etherlink blockchain and connect to applications through the WalletConnect protocol, such as MetaMask + +## Connecting to Beacon wallets + +Unity applications can connect to Beacon wallets by showing a QR code that the user scans with a wallet app or by opening that app directly through the Beacon protocol. +For an example of this method, see [Quickstart](./quickstart). + +This method for connecting follows these general steps: + +1. The Unity application calls the `TezosAPI.ConnectWallet()` method and passes the Beacon wallet type: + + ```csharp + var walletProviderData = new WalletProviderData { WalletType = WalletType.BEACON }; + try + { + var result = await TezosAPI.ConnectWallet(walletProviderData); + _infoText.text = result.WalletAddress; + } + catch (WalletConnectionRejected e) + { + _infoText.text = "Wallet connection rejected"; + Debug.LogError($"Wallet connection rejected. {e.Message}\n{e.StackTrace}"); + } + catch (Exception e) + { + Debug.LogException(e); + } + ``` + +1. The Unity application connects in different ways depending on the platform: + + - On WebGL applications, the SDK uses the Beacon SDK to open a popup window that prompts the user to select a compatible wallet via a deep link or to show a QR code: + + The Beacon popup window with a QR code and a list of compatible wallets + + - On mobile applications, the application attempts to open a Beacon wallet on the same device directly. + + - On mobile applications, you can also generate a barcode yourself. + On mobile applications, the `TezosAPI.ConnectWallet()` method triggers the `PairingRequested` event, which you can use to make the `Tezos.QR.QrCodeGenerator` class generate a QR code and show it on the interface for the user to scan with a wallet app. + +1. Regardless of the connection method, the SDK runs the `WalletConnected` event and the `TezosAPI.ConnectWallet()` method returns information about the connected account. + +## Connecting to WalletConnect wallets + +Unity applications can connect to EVM wallets such as MetaMask by showing a popup window that helps users connect. +The popup window can show a QR code for wallet apps to scan or open wallet apps on devices directly. + +Follow these steps to connect to a wallet with the WalletConnect protocol: + +1. Install the Tezos Unity WalletConnect SDK: + + 1. Make sure the Tezos Unity SDK is installed as described in [Installing the SDK](/unity/quickstart#installing-the-sdk). + + 1. In your Unity project, in the Package Manager panel, click the `+` symbol and then click **Add package from git URL**. + + 1. Enter the URL `https://github.com/trilitech/tezos-wallet-connect-unity-sdk.git` and click **Add**. + + The Package Manager panel downloads and installs the WalletConnect SDK. + +1. In the Unity project, add a button that users click to connect their wallet and a button that users click to disconnect their wallet. +You will add code to these buttons in a later step. +You can also use a single button and change its behavior to connect or disconnect based on whether there is a currently connected wallet. + +1. Add a TextMeshPro text field to show information about the connection, such as the account address. + + The scene looks similar to this example: + + ![An example of how the scene might look with information text, connection buttons, and a space for the QR code](/img/unity/unity-scene-layout-walletconnect.png) + +1. In your Unity project, add a class in a script file to hold the code for the connection operations. +The class must inherit from the Unity `MonoBehaviour` class, as in this example: + + ```csharp + using System; + using Netezos.Encoding; + using Tezos.API; + using Tezos.Operation; + using Tezos.WalletProvider; + using TMPro; + using UnityEngine; + using UnityEngine.UI; + + public class MyScripts : MonoBehaviour + { + [SerializeField] private TMP_Text _infoText; + [SerializeField] private Button _connectButton; + [SerializeField] private Button _disconnectButton; + + private async void Awake() + { + await TezosAPI.WaitUntilSDKInitialized(); + + // Check for prior connections + if (TezosAPI.IsConnected()) _infoText.text = TezosAPI.GetConnectionAddress(); + + // Run functions when users click buttons + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + } + + private async void OnConnectClicked() + { + // Connect to an EVM wallet such as MetaMask + var walletProviderData = new WalletProviderData { WalletType = WalletType.WALLETCONNECT }; + try + { + var result = await TezosAPI.ConnectWallet(walletProviderData); + _infoText.text = result.WalletAddress; + } + catch (WalletConnectionRejected e) + { + _infoText.text = "Wallet connection rejected"; + Debug.LogError($"Wallet connection rejected. {e.Message}\n{e.StackTrace}"); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + private async void OnDisconnectClicked() + { + // Disconnect the currently connected wallet + try + { + var result = await TezosAPI.Disconnect(); + _infoText.text = "Disconnected"; + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + } + ``` + + This code includes: + + - Objects that represent the buttons and a text field to show information on the screen + - An `Awake()` (or `Start()`) method that waits for the `TezosAPI.WaitUntilSDKInitialized()` method to complete, which indicates that the SDK is ready + - A check to see if a wallet is already connected, because Beacon can automatically remember previously connected wallets + - Listeners to run when users click the buttons, in this case a connect button and a disconnect button + +1. On the component that represents your script, drag the connection buttons and text information field to bind them to the objects in your script, as in this image: + + ![Binding the buttons and text field to the objects in your script](/img/unity/unity-scripts-walletconnect.png) + +1. Play the scene. + +1. When the scene loads, click the connection button. + + The application shows a WalletConnect popup window with an option to open compatible wallet apps or show a QR code. + +1. In your Tezos wallet, scan the QR code and connect to the application. + +## Connecting to social wallets + +Social wallets exist as federated identity accounts managed by web apps such as [Kukai](https://kukai.app/). +To connect to a social wallet, the Unity application calls + +To connect to a social wallet, the Unity WebGL application calls `Wallet.Connect()` with the `walletProvider` parameter set to `WalletProviderType.kukai`. + +Follow these steps to connect the application to social wallets: + +1. For testing purposes, set up a local social login server. +This server acts as the federated identity server that manages user accounts. + + 1. Run the example server at https://github.com/trilitech/social-login-web-client. + + 1. Open the server in a web browser at http://localhost:3000. + + 1. Use the Kukai log in window to log in to a social account: + + The Kukai login window + + 1. In the browser console, search for the phrase `OPENING DEEPLINK` and copy the URL for the deep link, which starts with `unitydl001://kukai-embed/`. + +1. Configure the test script for social logins: + + 1. In the Unity application, add a script named `DeepLinkTester.cs` with this code: + + ```csharp + using System.Reflection; + using UnityEngine; + + namespace Samples.RefactorExample + { + public class DeepLinkTester : MonoBehaviour + { + public string deepLinkURL = ""; + + [ContextMenu("Trigger Deep Link")] + public void SimulateDeepLinkActivation() + { + // Use reflection to invoke the internal InvokeDeepLinkActivated method + var methodInfo = typeof(Application).GetMethod("InvokeDeepLinkActivated", BindingFlags.NonPublic | BindingFlags.Static); + + methodInfo?.Invoke(null, new object[] + { + deepLinkURL + }); + } + } + } + ``` + + 1. Add the script to the canvas, open it, and add the URI in the **Deep Link URL** field: + + Setting the URL + +1. In the Unity application, call the `TezosAPI.SocialLogIn()` method and passes the Kukai wallet type: + + ```csharp + try + { + SocialProviderData socialProviderData = new SocialProviderData { SocialLoginType = SocialLoginType.Kukai }; + var result = await TezosAPI.SocialLogIn(socialProviderData); + _infoText.text = result.WalletAddress; + Debug.Log(result.WalletAddress); + } + catch (SocialLogInFailed e) + { + _infoText.text = "Social login rejected"; + Debug.LogError($"Social login rejected. {e.Message}\n{e.StackTrace}"); + } + catch (Exception e) + { + Debug.LogException(e); + } + ``` + +1. Bind the code that uses `TezosAPI.SocialLogIn()` to a button. + +1. Test the application by running it: + + 1. Run the application. -### QR code connections + 1. Click the button that triggers the `TezosAPI.SocialLogIn()` code. -This method generates a QR code that a user scans with their wallet application: + 1. In the `DeepLinkTester.cs` script, click the properties and then click **Trigger Deep Link**: -1. The Unity application calls the [`Wallet.Connect()`](/unity/reference/Wallet#connect) method with the `walletProvider` parameter set to `WalletProviderType.beacon` to send a connection request to a wallet application via the [TZIP-10 protocol](https://gitlab.com/tezos/tzip/-/tree/master/proposals/tzip-10). -1. The wallet returns a handshake that includes pairing information for the wallet, which triggers the `HandshakeReceived` event. -1. From the handshake information, the SDK generates a QR code. -The `TezosAuthenticator` prefab handles the QR code generation with the `QrCodeGenerator` class. -1. The user scans the QR code with their wallet app and approves the connection. -1. The SDK receives the connection approval, which triggers the `WalletConnected` event and includes information about the connected account. + Triggering the URL for the deep link -### Deep link connections +1. The deep link provides the connection information to the SDK and the call to `TezosAPI.SocialLogIn()` resolves with the wallet connection. -Deep link connections open the user's wallet app directly, which can be a mobile app or a browser extension. -This method relies on the Beacon SDK to interact with wallet apps: +When you are ready to deploy the Unity app to production, you must run a social login server and make the application use it: -1. The Unity WebGL application calls the [`Wallet.Connect()`](/unity/reference/Wallet#connect) method with the `walletProvider` parameter set to `WalletProviderType.beacon`. -The Beacon SDK detects that it is running in a web application and opens a popup window with the wallets that Beacon can connect to: +1. Run the social login server using the example at https://github.com/trilitech/social-login-web-client. - Beacon popup window with wallet types including Temple and Umami +1. In the `Assets/Tezos/Resources/TezosConfig.asset` object, in the **Kukai Web Client Address** field, add the URL of your social login server to use. +This is a server that you run tp handle authentication for your application. +For an example, see https://github.com/trilitech/social-login-web-client. -1. The [Beacon](https://walletbeacon.io/) SDK handles the process of connecting to the wallet. -1. The SDK receives the connection approval, which triggers the `WalletConnected` event and includes information about the connected account. +Now when the app is deployed it sends users to your server to log in and the server returns a deep link to the app. -### Social connections +## Checking the connection type -Social wallets exist as accounts managed by web apps such as [Kukai](https://kukai.app/). +To verify that the application is connected to a wallet, use one of these methods: -To connect to a social wallet, the Unity WebGL application calls [`Wallet.Connect()`](/unity/reference/Wallet#connect) with the `walletProvider` parameter set to `WalletProviderType.kukai`. +- `TezosAPI.IsConnected()`: Returns true if any kind of wallet is connected to the application and false if not. +- `TezosAPI.IsWalletConnected()`: Returns true if a Beacon or WalletConnect wallet is connected. +- `TezosAPI.IsSocialLoggedIn()`: Returns true if a social wallet is connected. - +To distinguish between Beacon and WalletConnect wallets, use `TezosAPI.GetWalletConnectionData()`. +This method returns a `WalletProviderData` object that includes information about the connected wallet and account. +Its `WalletType` field is `WalletType.BEACON` for Beacon wallets and `WalletType.WALLETCONNECT` for WalletConnect wallets. ## Disconnecting It's important to provide a disconnect button so the user can disconnect when they are finished with the application or if they want to connect with a different account. -To disconnect the active wallet, call the [`Wallet.Disconnect()`](/unity/reference/Wallet#disconnect) method. +To disconnect the active wallet, call the `Wallet.Disconnect()` method. +This method triggers the `WalletDisconnected` event and removes the connection from the wallet app. +For Beacon connections, it removes the connection from the persistent memory. diff --git a/docs/unity/managing-contracts.md b/docs/unity/managing-contracts.md deleted file mode 100644 index 81e7d912a..000000000 --- a/docs/unity/managing-contracts.md +++ /dev/null @@ -1,301 +0,0 @@ ---- -title: Managing contracts -authors: Tim McMackin -last_update: - date: 18 December 2023 ---- - -Smart contracts are backend programs that run on the Tezos blockchains. -Smart contracts can do many tasks, but for gaming they have two main purposes: - -- They handle tokens, which are digital assets stored on the blockchain -- They provide backend logic that users can trust because it cannot change - -For more information about contracts, see [Smart contracts](/smart-contracts). - -You can create your own smart contracts or use the built-in contract that the SDK provides for managing tokens in Unity projects. - -The Contract tutorial scene shows how to deploy a copy of the built-in contract from a Unity project. - -## The built-in contract - -The SDK includes a built-in contract that you can use to manage tokens for your Unity projects. - -The contract has entrypoints that allow you to create and transfer tokens. -See [Managing tokens](/unity/managing-tokens). - -The Michelson source code of the built-in contract is in the `Resources/Contracts` folder of the SDK, but it isn't very human-readable. -For a list of the entrypoints in the contract, see [TokenContract object](/unity/reference/TokenContract). -For an example of a deployed contract, see https://ghostnet.tzkt.io/KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY/entrypoints. - -## Deploying the built-in contract - -To deploy the built-in contract, call the [`TokenContract.Deploy()`](/unity/reference/TokenContract#deploy) method and pass a callback function: - -```csharp -public void DeployContract() -{ - TezosManager - .Instance - .Tezos - .TokenContract - .Deploy(OnContractDeployed); -} - -private void OnContractDeployed(string contractAddress) -{ - Debug.Log(contractAddress); -} -``` - -The project sends the deployment transaction to the connected wallet, which must approve the transaction and pay the related fees. -The callback function receives the address of the deployed contract, which the project uses to send requests to the contract. -It can take a few minutes for the contract to deploy and be confirmed in multiple blocks on the blockchain. - -The address that deployed the contract becomes the administrator of the contract and is the only account that can create tokens. - -The SDK provides information about the contract such as its address in the [`TokenContract`](/unity/reference/TokenContract) object. -You can use block explorers such as [Better Call Dev](https://better-call.dev/) to see information about the deployed contract. - -For information about using the built-in contract, see [Managing tokens](/unity/managing-tokens). - -## Getting the contract address - -When you deploy a contract with the [`TokenContract.Deploy()`](/unity/reference/TokenContract#deploy) method, the SDK saves the contract address by running this code: - -```csharp -PlayerPrefs.SetString("CurrentContract:" + Tezos.Wallet.GetActiveAddress(), contractAddress); -``` - -Then during SDK initialization, the SDK saves the address to the [`TokenContract.Address`](/unity/reference/TokenContract) property. - -To retrieve the address of contracts that you haven't deployed through the project, you can use the [`API.GetOriginatedContractsForOwner()`](/unity/reference/API#getoriginatedcontractsforowner) method. - -## Calling contracts - -The built-in contract has convenience methods for minting and transferring tokens; see [Managing tokens](/unity/managing-tokens). - -To call the contract's other entrypoints, use the [`Wallet.CallContract()`](/unity/reference/Wallet#callcontract) method. -For example, to call the contract's `set_administrator` entrypoint to set a new administrator account, use this code: - -```csharp -TezosManager.Instance.Tezos.Wallet.CallContract( - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - entryPoint: "set_administrator", - input: new MichelineString(newAdminAddress).ToJson() -); -``` - -For information about the entrypoints in the built-in contract, see [Unity SDK TokenContract object](/unity/reference/TokenContract#entrypoints). - -You can call any other contract by using its address, entrypoint name, and parameter value, as in this example: - -```csharp -TezosManager.Instance.Tezos.Wallet.CallContract( - contractAddress: address, - entryPoint: entryPointName, - input: new MichelineInt(12).ToJson() -); -``` - -This example passes the value 12 to the entrypoint in the variable `entryPointName`. - -Note that the parameter is encoded as a Michelson value. -For information about encoding more complex parameters, see [Encoding parameters](#encoding-parameters). - -To get the hash of the transaction, use the `ContractCallCompleted` event. - -## Encoding parameters - -When you call contract entrypoints or views with the `Wallet.CallContract()` or `Wallet.ReadView()` methods, you must encode the parameter as a Micheline value. -For example, if an entrypoint accepts two integers and one string as parameters, you must pass a list of two `Netezos.Encoding.MichelineInt` values and one `Netezos.Encoding.MichelineString` value: - -```csharp -var input = new MichelinePrim -{ - Prim = PrimType.Pair, - Args = new List - { - new MichelineInt(1), - new MichelineInt(2), - new MichelineString("My string value") - } -}.ToJson(); - -TezosManager.Instance.Tezos.Wallet.CallContract( - contractAddress: address, - entryPoint: entryPointName, - input: input -); -``` - -You can also use the value of the parameters in Michelson JSON. -The previous example looks like this with a JSON parameter value: - -```csharp -var input = @"{ - ""prim"": ""Pair"", - ""args"": [ - { - ""int"": ""1"" - }, - { - ""prim"": ""Pair"", - ""args"": [ - { - ""int"": ""2"" - }, - { - ""string"": ""My string value"" - } - ] - } - ] -}"; - -TezosManager.Instance.Tezos.Wallet.CallContract( - contractAddress: address, - entryPoint: entryPointName, - input: input -); -``` - -Some block explorers allow you to fill in parameter values for an entrypoint and then download the Michelson JSON to use in your code. - -You can build more complex parameters out of `Netezos.Encoding` objects. -For example, the built-in contract has an entrypoint named `update_operators`, which is an FA2 standard entrypoint that gives an account control over another account's tokens. -It accepts a list of changes to make to token operators, each including these fields in this order: - -- Either "add_operator" or "remove_operator" -- The address of the operator, which will be able to control the owner's tokens of the specified ID. -- The ID of the token -- The address of the token owner - -This is the Michelson parameter type for the endpoint: - -``` -(list %update_operators (or - (pair %add_operator (address %owner) - (pair (address %operator) - (nat %token_id))) - (pair %remove_operator (address %owner) - (pair - (address %operator) - (nat %token_id))))) -``` - -In this case, you set the "add_operator" value by passing a `PrimType.Left` Michelson primitive or the "remove_operator" value by passing a `PrimType.Right` primitive. -The values in the primitive are a series of nested pairs called a [right comb](/smart-contracts/data-types/complex-data-types#right-combs), as in this example: - -```json -{ - "prim": "LEFT", - "args": [ - { - "prim": "Pair", - "args": [ - { - "string": "tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx" - }, - { - "prim": "Pair", - "args": [ - { - "string": "tz1hQKqRPHmxET8du3fNACGyCG8kZRsXm2zD" - }, - { - "int": "1" - } - ] - } - ] - } - ] -} -``` - -The code to create a list of these elements to pass to the entrypoint looks like this: - -```csharp -var operatorAddress = "tz1hQKqRPHmxET8du3fNACGyCG8kZRsXm2zD"; -var ownerAddress = "tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx"; -int[] tokenIds = {1, 2, 3}; - -var operatorArray = new MichelineArray(); -foreach (var tokenId in tokenIds) -{ - operatorArray.Add(new MichelinePrim - { - Prim = PrimType.Left, - Args = new List - { - new MichelinePrim - { - Prim = PrimType.Pair, - Args = new List - { - new MichelineString(ownerAddress), - new MichelinePrim - { - Prim = PrimType.Pair, - Args = new List - { - new MichelineString(operatorAddress), - new MichelineInt(tokenId) - } - } - - } - } - } - }); -}; - -TezosManager.Instance.Tezos.Wallet.CallContract( - contractAddress: address, - entryPoint: "update_operators", - input: operatorArray.ToJson() -); -``` - -## Deploying other contracts - -To deploy a contract from Unity, you must compile the contract to Michelson in JSON format. -For example, to compile a contract in LIGO to Michelson JSON, run this code: - -```bash -ligo compile contract MyContract.jsligo \ - -m MyContract -o MyContract.json --michelson-format json -``` - -Then, ensure that the code of the code and initial storage value of the contract are wrapped in `code` and `storage` fields at the root of the file, as in this example: - -```json -{ - "code": [ - { - "prim": "parameter", - "args": [ - ... - }, - ], - "storage": { - "int": "0" - } -} -``` - -To deploy the contract from the Unity project, use the [`Wallet.OriginateContract()`](/unity/reference/Wallet#originatecontract) method, as in this example: - -```csharp -var contractJSON = Resources.Load("Contracts/MyContract").text; -TezosManager.Instance.Tezos.Wallet.OriginateContract(contractJSON); -``` - -To get the address of the deployed contract, use the `ContractCallCompleted` event. - - - diff --git a/docs/unity/managing-tokens.md b/docs/unity/managing-tokens.md index e18f06914..4e99ec147 100644 --- a/docs/unity/managing-tokens.md +++ b/docs/unity/managing-tokens.md @@ -2,10 +2,10 @@ title: Managing tokens authors: Tim McMackin last_update: - date: 11 January 2024 + date: 19 November 2024 --- -The SDK's built-in contract is compatible with the [FA2 token standard](/architecture/tokens/FA2), which means that you can use a single smart contract to manage any number of types of tokens, including: +Tezos supports a variety of types of tokens, including: - Fungible tokens, which are collections of interchangeable tokens with a quantity that you define. Fungible tokens can be quantifiable commodities like in-game currency, fuel, ammunition, or energy, or they can be identical items with a limited quantity. @@ -14,144 +14,232 @@ Games use NFTs for items that are unique and must not be duplicated. You can create as many tokens and types of tokens as you need in one contract, but each transaction to create or transfer tokens incurs fees. -## Creating (minting) tokens +For more information about tokens, see [Tokens](/architecture/tokens). -To create a token type, call the contract's `mint` entrypoint and pass these parameters: +## FA2 tokens -- A callback function to run when the token is created -- The metadata for the token, which includes a name and description, URIs to preview media or thumbnails, and how many decimal places the token can be broken into -- The destination account that owns the new tokens, which can be a user account, this smart contract, or any other smart contract -- The number of tokens to create +While you can create tokens that behave in any way that you want them to behave, it's best to create tokens that follow a standard. +The Tezos [FA standards](/architecture/tokens#token-standards) enforce a standard format for tokens which allows applications like games, wallets, and block explorers to work with them in a consistent way. +For example, if you create an FA-compatible token and use it in a Unity application, players can look up information about their tokens in block explorers and transfer them with their wallets without interacting with the Unity application. -For example, this code creates a token type with a quantity of 100: +For this reason, Unity applications should use FA tokens whenever possible. -```csharp -var initialOwner = TezosManager - .Instance - .Wallet - .GetActiveAddress(); +The most popular and commonly-supported FA standard is [FA2](/architecture/tokens/FA2), so the examples on this page are for working with FA2 tokens. +FA2 tokens can be fungible tokens or non-fungible tokens, which makes the standard flexible enough for most use cases. -const string imageAddress = "ipfs://QmX4t8ikQgjvLdqTtL51v6iVun9tNE7y7Txiw4piGQVNgK"; +## FA2 token contracts -var tokenMetadata = new TokenMetadata -{ - Name = "My token", - Description = "Description for my token", - Symbol = "MYTOKEN", - Decimals = "0", - DisplayUri = imageAddress, - ArtifactUri = imageAddress, - ThumbnailUri = imageAddress -}; +To create and work with FA2 tokens you must deploy an FA2-compatible smart contract. +For examples of FA2 contracts, see [Sample smart contracts](/smart-contracts/samples). +You can also use the tutorial [Create a fungible token with the SmartPy FA2 library](/smart-contracts/samples) to walk through the process of creating, customizing, and deploying an FA2 contract. -TezosManager - .Instance - .Tezos - .TokenContract - .Mint( - completedCallback: OnTokenMinted, - tokenMetadata: tokenMetadata, - destination: initialOwner, - amount: 100); - -private void OnTokenMinted(TokenBalance tokenBalance) -{ - Debug.Log($"Successfully minted token with Token ID {tokenBalance.TokenId}"); -} +:::note + +The rest of this page assumes that you are using FA2 tokens. + +::: + +:::note + +You can use block explorers for help formatting the parameters for contract calls. +See [Encoding parameters as JSON strings](/unity/calling-contracts#encoding-parameters-as-json-strings). + +::: + +## Creating (minting) tokens + +The FA2 standard does not require contracts to have a `mint` entrypoint that creates tokens, but many do. +The `mint` entrypoint may be limited so only certain accounts can call it, or it may have other restrictions. +If a contract does not have a `mint` entrypoint, it was created with all of the tokens that it will ever have and therefore no more tokens can be minted. + +A typical FA2 `mint` entrypoint accepts the token ID, the number of tokens to create, and the initial owner of the new tokens. +For example, the contract `KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY` has a `mint` entrypoint that accepts this parameter in JSON format: + +```json +"schema:list:object": [ + { + "to_:address": "address", + "token:or": { + "existing:nat": "nat", + "new:map_flat:string:bytes": { + "string": "bytes" + } + }, + "amount:nat": "nat" + } +] ``` -For a complete example of creating tokens, see the file `TezosSDK/Examples/Contract/Scripts/MintToken.cs` and the Contract tutorial scene. +The equivalent Michelson parameter looks like this: -## Transferring tokens +```michelson +(list %mint (pair (address %to_) + (pair (or %token (nat %existing) (map %new string bytes)) (nat %amount)))) +``` -To transfer tokens, call the contract's `Transfer` entrypoint and pass these parameters: +In this case, the `mint` entrypoint can create tokens of an existing type or create a new type of token. -- A callback function to run when the transfer is complete -- The account to transfer the tokens to -- The ID of the token -- The amount of tokens to transfer +As described in [Encoding parameters](/unity/calling-contracts#encoding-parameters), you can encode the parameter for the call as a Micheline object via the Netezos library or as a JSON string. -This example transfers 12 tokens with the ID 5 to the account in the variable `destinationAccountAddress`. +To encode the parameter as a JSON object, you can fill in the fields on the block explorer and generate a JSON file like this example, which mints 10 tokens of type 0: ```csharp -public void HandleTransfer() -{ - TezosManager - .Instance - .Tezos - .TokenContract - .Transfer( - completedCallback: TransferCompleted, - destination: destinationAccountAddress, - tokenId: 5, - amount: 12); -} +var mintJsonString = "[{\"prim\":\"Pair\",\"args\":[{\"string\":\"tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx\"},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Left\",\"args\":[{\"int\":\"0\"}]},{\"int\":\"10\"}]}]}]"; -private void TransferCompleted(string txHash) +var mintTokensRequest = new OperationRequest { - Logger.LogDebug($"Transfer complete with transaction hash {txHash}"); -} -``` - -For a complete example, see the Transfer tutorial scene. + Destination = "KT1HP6uMwf829cDgwynZJ4rDvjLCZmfYjja1", + EntryPoint = "mint", + Arg = mintJsonString, + Amount = "0", +}; -## Getting token balances +var response = await TezosAPI.RequestOperation(mintTokensRequest); +``` -To get the tokens that the connected account owns, call the [`API.GetTokensForOwner()`](/unity/reference/API#gettokensforowner) method in a coroutine. -This example prints information about the tokens that the account owns to the log: +To encode the parameter with the Netezos library, use primitives organized by pairs. +In this example, the parameter uses a Left value in an Or primitive to represent the Micheline field `nat %existing`: ```csharp -private void Start() +// Owner of the new tokens +var to_ = new MichelineString("tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx"); +// Number of tokens to mint +var amount = new MichelineInt(10); +var token = new MichelinePrim { - // Subscribe to account connection event - TezosManager.Instance.EventManager.WalletConnected += OnWalletConnected; -} + Prim = PrimType.Pair, // Existing token type + Args = new List + { + new MichelinePrim + { + Prim = PrimType.Left, + Args = new List + { + // ID of token type + new MichelineInt(0), + } + }, + amount + } +}; + +var parameter = new MichelineArray +{ + new MichelinePrim + { + Prim = PrimType.Pair, + Args = new List + { + to_, + token + } + } +}.ToJson(); -private void OnWalletConnected(WalletInfo walletInfo) +var mintTokensRequest = new OperationRequest { - // Address of the connected wallet - var address = walletInfo.Address; + Destination = "KT1HP6uMwf829cDgwynZJ4rDvjLCZmfYjja1", + EntryPoint = "mint", + Arg = parameter, + Amount = "0", +}; - // Prepare the coroutine to fetch the tokens - var routine = TezosManager.Instance.Tezos.API.GetTokensForOwner( - OnTokensFetched, // Callback to be called when the tokens are fetched - address, true, 10_000, new TokensForOwnerOrder.ByLastTimeAsc(0)); +var response = await TezosAPI.RequestOperation(mintTokensRequest); +``` - StartCoroutine(routine); -} +## Transferring tokens + +To transfer tokens, pass the source account, target account, token ID, and quantity to the contract's `transfer` entrypoint. +The account that sends the transfer call must be the owner or operator of the tokens. +For more information about token access control, see [FA2 tokens](/architecture/tokens/FA2). + +This example transfers 2 tokens with the ID 7: + +```csharp +var transferTokensString = "[ { \"prim\": \"Pair\", \"args\": [ { \"string\": \"tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx\" }, [ { \"prim\": \"Pair\", \"args\": [ { \"string\": \"tz1hQKqRPHmxET8du3fNACGyCG8kZRsXm2zD\" }, { \"prim\": \"Pair\", \"args\": [ { \"int\": \"7\" }, { \"int\": \"2\" } ] } ] } ] ] } ]"; -private void OnTokensFetched(IEnumerable tokenBalances) +var transferTokensRequest = new OperationRequest { - var walletAddress = TezosManager.Instance.Wallet.GetWalletAddress(); - var contractAddress = TezosManager.Instance.Tezos.TokenContract.Address; + Destination = "KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY", + EntryPoint = "transfer", + Arg = transferTokensString, + Amount = "0", +}; - var tokens = new List(tokenBalances); +var response = await TezosAPI.RequestOperation(transferTokensRequest); +``` - // Filter the tokens by the current contract address - var filteredTokens = tokens.Where(tb => tb.TokenContract.Address == contractAddress).ToList(); +This code runs the same operation, but it uses Netezos types instead of raw JSON: - if (filteredTokens.Count > 0) +```csharp +// Source account +var from_ = new MichelineString("tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx"); +// Target account +var to_ = new MichelineString("tz1hQKqRPHmxET8du3fNACGyCG8kZRsXm2zD"); +// Token ID +var tokenId = new MichelineInt(7); +// Amount +var amount = new MichelineInt(2); + +var parameter = new MichelineArray +{ + new MichelinePrim { - foreach (var tb in filteredTokens) + Prim = PrimType.Pair, + Args = new List { - Debug.Log($"{walletAddress} has {tb.Balance} tokens on contract {tb.TokenContract.Address}"); - Debug.Log(tb.TokenMetadata); + from_, + new MichelineArray + { + new MichelinePrim + { + Prim = PrimType.Pair, + Args = new List + { + to_, + new MichelinePrim + { + Prim = PrimType.Pair, + Args = new List + { + tokenId, + amount + } + } + } + } + } } } - else - { - Debug.Log($"{walletAddress} has no tokens in the active contract"); - } +}.ToJson(); + +var transferTokensRequest = new OperationRequest +{ + Destination = "KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY", + EntryPoint = "transfer", + Arg = parameter, + Amount = "0", +}; + +var response = await TezosAPI.RequestOperation(transferTokensRequest); +``` + +## Getting token balances + +You can get information about the tokens in a contract by passing the address of the contract and the maximum number of tokens to return to the `TezosAPI.GetTokens()` method. +The response is a list of `TokenData` objects with information about the tokens: + +```csharp +var tokenList = await TezosAPI.GetTokens>("KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY", 20); +foreach (TokenData token in tokenList) +{ + Debug.Log($"Token ID {token.TokenId} has {token.HoldersCount} owners."); } ``` ## Destroying (burning) tokens -The built-in contract does not have a burn entrypoint, so you can't destroy its tokens. -If you want to make tokens unusable, send them to an address that doesn't exist or to an account that you can't use. +The FA2 standard does not have a standard way of burning tokens. +Some FA2 implementations have a `burn` entrypoint. +In other cases, if you want to make tokens unusable, send them to an address that doesn't exist or to an account that you can't use. For example, you can create an account in a wallet app, send the tokens to it, and delete the private key for the account. - - \ No newline at end of file diff --git a/docs/unity/prefabs.md b/docs/unity/prefabs.md deleted file mode 100644 index e7e44d2b5..000000000 --- a/docs/unity/prefabs.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Unity SDK prefabs -sidebar_label: Prefabs -authors: Tim McMackin -last_update: - date: 11 January 2024 ---- - -The Tezos Unity SDK provides these prefabs: - -## TezosManager - -This prefab sets the metadata for the scene, such as the application name that users see in their wallet applications before connecting to the project. -It also initializes the Tezos SDK for use in the scene and creates an instance of the `TezosSDK.Tezos.Tezos` class, which provides access to the SDK objects such as the [Wallet](/unity/reference/Wallet) and [EventManager](/unity/reference/EventManager) objects. - -Its fields control what users see in their wallet applications before connecting to the project, as shown in this picture of the Inspector panel: - -The Inspector panel, showing information about the project - -## TezosAuthenticator - -This prefab provides code to connect to different kinds of Tezos wallets. - -If you copy this prefab into your scene and run the scene, it shows a QR code or connection buttons that Tezos wallet applications can scan to connect with the application. -Whether it shows the QR code or buttons depends on whether the project is running in standalone, mobile, or WebGL mode. -You can access these features through the prefab and change how the project manages its connection to users' wallets. - -The prefab's `LoginPanel` object includes objects that connect to wallets in different ways: - -- The `QRCode` object shows a QR code that wallet apps can scan to connect -- The `LoginButtonDeepLink` object shows a button that opens a wallet app on a mobile device or a wallet browser extension in a web browser via the Beacon SDK -- The `SocialLoginButton` object shows a button that opens a social wallet, such as Kukai - -For details about how the prefab works, see the file `TezosAuthenticator.cs`. - -For an example of the prefab in use, see the [WalletConnection tutorial scene](/unity/scenes#wallet-connection-scene). diff --git a/docs/unity/quickstart.md b/docs/unity/quickstart.md index c6999de60..d471b5411 100644 --- a/docs/unity/quickstart.md +++ b/docs/unity/quickstart.md @@ -2,7 +2,7 @@ title: Quickstart authors: Tim McMackin last_update: - date: 11 January 2024 + date: 20 November 2024 --- Follow these steps to install the Tezos Unity SDK in an existing Unity project and start using it. @@ -12,7 +12,6 @@ These instructions cover: - Installing the SDK into an existing Unity project - Testing that the SDK works in your project - Connecting to a user's Tezos wallet -- Creating and managing tokens - Prompting the user to sign messages ## Installing the SDK @@ -24,33 +23,11 @@ These instructions cover: The Package Manager panel downloads and installs the SDK. You can see its assets in the Project panel under Packages > Tezos Unity SDK. -1. Ensure that you have a Tezos-compatible wallet configured for the Ghostnet testnet on your mobile device. +1. Ensure that you have a Tezos-compatible wallet configured for the Ghostnet test network on your mobile device. +By default, the SDK uses Ghostnet instead of Tezos Mainnet. For instructions, see [Installing and funding a wallet](/developing/wallet-setup). -1. If you want to publish the project to WebGL, follow the steps in [Enabling WebGL support](#enabling-webgl-support). - -1. To import the tutorial scenes, see [Scenes](/unity/scenes). - -## Enabling WebGL support - -The Unity SDK provides a WebGL template that you can use to publish Unity projects to run in a web browser. -Follow these steps to set up the Tezos SDK to work with WebGL: - -1. In the Unity Editor, go to the Project panel and expand the **Packages > Tezos Unity SDK > WebGLFrontend** folder. -1. From the `WebGLFrontend/output` folder, copy the `StreamingAssets` and `WebGLTemplates` folders into the `Assets` folder of your project. - -1. Select the AirGap template to use in the WebGL build: - - 1. Click **Edit > Project Settings**. - 1. Go to the **Player** tab. - 1. On the Player tab, go to the **WebGL settings** tab. - 1. Under **Resolution and Presentation**, select the AirGap WebGL template, as shown in this picture: - - The project settings, with the Airgap WebGL template selected - -1. To enable copy and paste in the WebGL build, double-click `_WebGLCopyAndPaste.unitypackage`, which is in the `WebGLFrontend/output` folder of the SDK, to install it. - - This package automatically enables copy and paste on selectable text fields, such as the account address field in the WalletConnection tutorial scene. + ## Connecting to wallets @@ -61,222 +38,245 @@ Users must still confirm all transactions in their wallet application. Using a wallet application in this way saves you from having to implement payment processing and security in your application. Game developers can also use the wallet and its account as a unique account identifier and as the user's inventory. -1. Copy the `TezosAuthenticator` and `TezosManager` prefabs to your scene. -These prefabs provide prerequisites to use Tezos in a scene and help connect to accounts. -For more information about them, see [Prefabs](/unity/prefabs). +The SDK supports three types of wallets: - The `TezosAuthenticator` prefab automatically adds features that connect to users' wallets. - If you copy these prefabs into your scene and run it, it shows a QR code or connection buttons that Tezos wallet applications can scan to connect with the application. - Whether it shows the QR code or buttons depends on whether the project is running in standalone, mobile, or WebGL mode. +- Tezos wallets that connect through the Beacon protocol, such as Temple +- Tezos social wallets that connect to a federated identity login through [Kukai](https://wallet.kukai.app) +- Ethereum wallets that connect through the WalletConnect protocol, such as MetaMask -1. Add features to your project to use the connected account. -For example, the `Tutorials/Common/Scripts/WalletInfoUI.cs` file responds to the `WalletConnected` event, which runs when the user approves the connection in their wallet application. -You can use this event to get the address of the connected account, as in this code: +The SDK can connect to these wallets in different ways depending on the platform. +For example, in a WebGL application, it can show a QR code to allow the user to scan it with a wallet app on a mobile device. +If the Unity application is running on a mobile app, it can open Tezos wallets on the mobile device directly, known as a _deep link_. - ```csharp - private void Start() - { - addressText.text = NOT_CONNECTED_TEXT; +For more details, see [Connecting accounts](/unity/connecting-accounts). - // Subscribe to events; - TezosManager.Instance.EventManager.WalletConnected += OnWalletConnected; - TezosManager.Instance.EventManager.WalletDisconnected += OnWalletDisconnected; - } +These instructions are for connecting to Tezos wallets through the Beacon protocol: - private void OnWalletConnected(WalletInfo walletInfo) - { - // We can get the address from the wallet - addressText.text = TezosManager.Instance.Wallet.GetWalletAddress(); - // Or from the event data - addressText.text = walletInfo.Address; - } +1. In the Unity project, add a button that users click to connect their wallet and a button that users click to disconnect their wallet. +You will add code to these buttons in a later step. +You can also use a single button and change its behavior to connect or disconnect based on whether there is a currently connected wallet. - private void OnWalletDisconnected(WalletInfo walletInfo) - { - addressText.text = NOT_CONNECTED_TEXT; - } - ``` +1. Add a RawImage component to the project to hold the QR code and make it square and large enough that mobile devices can scan it. - You can use this address as a user's account ID because Tezos account addresses are unique. +1. Add a TextMeshPro text field to show information about the connection, such as the account address. -1. To respond to other events, add listeners for the events that the SDK provides. -You can see these events and their return values in the [EventManager object](/unity/reference/EventManager). + The scene looks similar to this example: -For an example, see the [WalletConnection tutorial scene](/unity/scenes#wallet-connection-scene). + ![An example of how the scene might look with information text, connection buttons, and a space for the QR code](/img/unity/unity-scene-layout-beacon.png) -## Deploying contracts +1. In your Unity project, add a class in a script file to hold the code for the connection operations. +The class must inherit from the Unity `MonoBehaviour` class, as in this example: -Contracts are backend programs that run on the Tezos blockchains. -Smart contracts can do many tasks, but for gaming they have two main purposes: + ```csharp + using System; + using Netezos.Encoding; + using Tezos.API; + using Tezos.Operation; + using Tezos.QR; + using Tezos.WalletProvider; + using TMPro; + using UnityEngine; + using UnityEngine.UI; + + public class MyScripts : MonoBehaviour + { + [SerializeField] private QrCodeGenerator _qrCodeGenerator; + [SerializeField] private TMP_Text _infoText; + [SerializeField] private Button _connectButton; + [SerializeField] private Button _disconnectButton; + + private async void Awake() + { + await TezosAPI.WaitUntilSDKInitialized(); + + // Check for prior connections + if (TezosAPI.IsConnected()) _infoText.text = TezosAPI.GetConnectionAddress(); + + // Run functions when users click buttons + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + + // Generate QR code when user connects + TezosAPI.PairingRequested += OnPairingRequested; + } + + private void OnPairingRequested(string data) + { + _qrCodeGenerator.SetQrCode(data); + } + + private async void OnConnectClicked() + { + // Connect to a Beacon wallet (such as Temple) + var walletProviderData = new WalletProviderData { WalletType = WalletType.BEACON }; + try + { + var result = await TezosAPI.ConnectWallet(walletProviderData); + _infoText.text = result.WalletAddress; + } + catch (WalletConnectionRejected e) + { + _infoText.text = "Wallet connection rejected"; + Debug.LogError($"Wallet connection rejected. {e.Message}\n{e.StackTrace}"); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + private async void OnDisconnectClicked() + { + // Disconnect the currently connected wallet + try + { + var result = await TezosAPI.Disconnect(); + _infoText.text = "Disconnected"; + } + catch (Exception e) + { + Debug.LogException(e); + } + } -- They handle tokens, which are digital assets stored on the blockchain -- They provide backend logic that users can trust because it cannot change + } + ``` -The ContractAndMinting tutorial scene shows how to deploy a contract from a Unity project. + This code includes: -The SDK provides a built-in contract that you can use instead of writing your own. -This contract manages different kinds of tokens. + - Objects that represent the buttons, the QR code generator (from the class `Tezos.QR.QrCodeGenerator`), and a text field to show information on the screen + - An `Awake()` (or `Start()`) method that waits for the `TezosAPI.WaitUntilSDKInitialized()` method to complete, which indicates that the SDK is ready + - A check to see if a wallet is already connected, because Beacon can automatically remember previously connected wallets + - Listeners to run when users click the buttons, in this case a connect button and a disconnect button + - A method to generate the QR code to connect to a mobile application -To deploy the built-in contract, call the [`TokenContract.Deploy()`](/unity/reference/TokenContract#deploy) method and pass a callback function: +1. In the Unity editor, create an object on the canvas to represent the script `QrCodeGenerator.cs`, which is available in the Project panel at `Packages/Tezos Unity SDK/Runtime/Scripts/QR/QrCodeGenerator.cs`. -```csharp -public void DeployContract() -{ - TezosManager - .Instance - .Tezos - .TokenContract - .Deploy(OnContractDeployed); -} +1. Bind the RawImage component to the `Raw Image` field of the script, as in this image: -private void OnContractDeployed(string contractAddress) -{ - Debug.Log(contractAddress); -} -``` + ![Binding the image to the QR code generator script](/img/unity/unity-quickstart-bind-rawimage.png) -The project sends the deployment transaction to the connected wallet, which must approve the transaction and pay the related fees. -The SDK stores the address of the contract as [`TokenContract.address`](/unity/reference/TokenContract). +1. On the component that represents your script, drag the connection buttons, text information field, RawImage component, and QR code generator script to bind them to the objects in your script, as in this image: -For an example, see the [ContractAndMinting tutorial scene](/unity/scenes#contractandminting-scene). + ![Binding the buttons and QR code generator script to the objects in your script](/img/unity/unity-quickstart-scripts-beacon.png) -## Creating tokens +1. Play the scene. -To create a token type, call the contract's `mint` entrypoint and pass these parameters: +1. When the scene loads, click the connection button. -- A callback function to run when the token is created -- The metadata for the token, which includes a name and description, URIs to preview media or thumbnails, and how many decimal places the token can be broken into -- The destination account that owns the new tokens, which can be a user account, this smart contract, or any other smart contract -- The number of tokens to create + The Unity player may try to open a URL that starts with `tezos://`. + The SDK is trying to connect to a Tezos wallet on a mobile device. + You can safely ignore and close this popup. -For example, this code creates a token type with a quantity of 100: + The application shows a QR code. -```csharp -// Get the address of the connected wallet -var initialOwner = TezosManager - .Instance - .Wallet - .GetWalletAddress(); - -// To preview the IPFS-hosted image: -// https://ipfs.io/ipfs/QmX4t8ikQgjvLdqTtL51v6iVun9tNE7y7Txiw4piGQVNgK -const string imageAddress = "ipfs://QmX4t8ikQgjvLdqTtL51v6iVun9tNE7y7Txiw4piGQVNgK"; - -// Prepare metadata -var tokenMetadata = new TokenMetadata -{ - Name = "My token", - Description = "Description for my token", - Symbol = "MYTOKEN", - Decimals = "0", - DisplayUri = imageAddress, - ArtifactUri = imageAddress, - ThumbnailUri = imageAddress -}; - -// Call the "mint" entrypoint of the contract -TezosManager - .Instance - .Tezos - .TokenContract - .Mint( - completedCallback: OnTokenMinted, - tokenMetadata: tokenMetadata, - destination: initialOwner, - amount: 100); - -// This callback is triggered after the contract call successfully completes and the resulting transaction is recorded on the blockchain. -private void OnTokenMinted(TokenBalance tokenBalance) -{ - Debug.Log($"Successfully minted token with Token ID {tokenBalance.TokenId}"); -} -``` +1. In your Tezos wallet, scan the QR code and connect to the application. -For an example, see the [ContractAndMinting tutorial scene](/unity/scenes#contractandminting-scene). +If the connection is correct, the text field shows the address of the connected account. -## Transferring tokens +Now the application is connected to the wallet and can submit transactions for it to approve and messages for it to sign. -To transfer tokens, call the contract's `Transfer` entrypoint and pass these parameters: + + +## Signing messages -- A callback function to run when the transfer is complete -- The account to transfer the tokens to -- The ID of the token -- The amount of tokens to transfer +You can use the connection to the user's wallet to prompt them to sign messages. +Signing a message proves that it came from a specific user's wallet because the wallet encrypts the message with the user's account's key. +In this way, game developers can make players sign a message as a way of validating their identity. -This example transfers 12 tokens with the ID 5 to the account in the variable `destinationAccountAddress`. +For example, this code prompts the user to sign the message "This message came from my account." +Then it uses the Netezos library to verify that the payload was signed by the currently connected account: ```csharp -public void HandleTransfer() -{ - TezosManager - .Instance - .Tezos - .TokenContract - .Transfer( - completedCallback: TransferCompleted, - destination: destinationAccountAddress, - tokenId: 5, - amount: 12); -} +string payload = "This message came from my account."; -private void TransferCompleted(string txHash) -{ - Logger.LogDebug($"Transfer complete with transaction hash {txHash}"); -} +var result = await TezosAPI.RequestSignPayload( + new SignPayloadRequest + { + Payload = payload, + SigningType = SignPayloadType.MICHELINE + } +); + +var publicKey = string.Empty; +if (TezosAPI.IsWalletConnected()) +publicKey = TezosAPI.GetWalletConnectionData().PublicKey; +if (TezosAPI.IsSocialLoggedIn()) +publicKey = TezosAPI.GetSocialLoginData().PublicKey; + +var verified = NetezosExtensions.VerifySignature( + publicKey, + Beacon.Sdk.Beacon.Sign.SignPayloadType.micheline, + payload, + result.Signature +); +Debug.Log($"Signature verified: {verified}"); ``` -For a complete example, see the [Transfer tutorial scene](/unity/scenes#transfer-scene). - -## Getting token balances + -To get the tokens that the connected account owns, call the [`API.GetTokensForOwner()`](/unity/reference/API#gettokensforowner) method in a coroutine. -This example prints information about the tokens that the account owns to the log: +## Calling smart contracts -```csharp -private void Start() -{ - // Subscribe to account connection event - TezosManager.Instance.EventManager.WalletConnected += OnWalletConnected; -} +Smart contracts are backend programs that run on the Tezos blockchains. +Smart contracts can do many tasks, but for gaming they have two main purposes: -private void OnWalletConnected(WalletInfo walletInfo) -{ - // Address of the connected wallet - var address = walletInfo.Address; +- They handle tokens, which are digital assets stored on the blockchain +- They provide backend logic that users can trust because it cannot change - // Prepare the coroutine to fetch the tokens - var routine = TezosManager.Instance.Tezos.API.GetTokensForOwner( - OnTokensFetched, // Callback to be called when the tokens are fetched - address, true, 10_000, new TokensForOwnerOrder.ByLastTimeAsc(0)); +To call a smart contract, the Unity application must be connected to a wallet. +The application sends the smart contract transaction to the user's wallet for approval. - StartCoroutine(routine); -} +For example, this code sends a transaction to the entrypoint `increment` of the smart contract `KT1R2LTg3mQoLvHtUjo2xSi7RMBUJ1sJkDiD`, passes the parameter `5`, and includes zero tez tokens. +When the transaction completes successfully, it logs the hash of the transaction. +You can use this hash to look up information about the transaction in a [block explorer](/developing/information/block-explorers). -private void OnTokensFetched(IEnumerable tokenBalances) +```csharp +private async void Awake() { - var walletAddress = TezosManager.Instance.Wallet.GetWalletAddress(); - var contractAddress = TezosManager.Instance.Tezos.TokenContract.Address; + await TezosAPI.WaitUntilSDKInitialized(); - var tokens = new List(tokenBalances); + _connectButton.onClick.AddListener(OnConnectClicked); + _disconnectButton.onClick.AddListener(OnDisconnectClicked); + _requestOperationButton.onClick.AddListener(OnRequestOperationClicked); - // Filter the tokens by the current contract address - var filteredTokens = tokens.Where(tb => tb.TokenContract.Address == contractAddress).ToList(); + TezosAPI.OperationResulted += OperationResulted; +} - if (filteredTokens.Count > 0) +private async void OnRequestOperationClicked() +{ + try { - foreach (var tb in filteredTokens) + var request = new OperationRequest { - Debug.Log($"{walletAddress} has {tb.Balance} tokens on contract {tb.TokenContract.Address}"); - Debug.Log(tb.TokenMetadata); - } + // Contract to call + Destination = "KT1R2LTg3mQoLvHtUjo2xSi7RMBUJ1sJkDiD", + // Entrypoint to call + EntryPoint = "increment", + // Parameter to pass, as a Michelson expression + Arg = new MichelineInt(5).ToJson(), + // Amount of tez to send with the transaction + Amount = "0", + }; + var response = await TezosAPI.RequestOperation(request); } - else + catch (Exception e) when (e is WalletOperationRejected or SocialOperationFailed) { - Debug.Log($"{walletAddress} has no tokens in the active contract"); + Debug.LogError($"Operation failed: {e.Message}"); } + catch (Exception e) + { + Debug.LogError($"Unexpected error during operation: {e.Message}"); + } +} + +private void OperationResulted(OperationResponse operationResponse) +{ + Debug.Log("Transaction hash: " + operationResponse.TransactionHash); } ``` +For more information, see [Calling contracts](/unity/calling-contracts). + ## Uploading files to IPFS The InterPlanetary File System (IPFS) is a protocol and peer-to-peer network for storing and sharing data in a distributed file system. @@ -284,21 +284,20 @@ Blockchain developers use it to store data such as token images and metadata. The SDK provides tools to upload to IPFS by using the [Pinata](https://pinata.cloud/) API, but you can set up IPFS upload in other ways. -To use the SDK, create instances of the Tezos Configuration and Data Provider Configuration objects and put your Pinata JWT (not the API key or secret) in the `TezosConfigSO` object's Pinata Api Key field. - -To use the SDK, see the code in the `UploadImageButton.cs` file, which handles uploading files in the IPFSUpload scene. -It has a UI upload button that triggers this method, which uses the built-in Pinata uploader to upload the file and get the URL for it: +To upload files to IPFS, put your Pinata API JWT (not the API key) in the `Pinata Api Token` field of the `Assets/Tezos/Resources/TezosConfig.asset` object. +Then you can upload to IPFS with this code: ```csharp public void HandleUploadClick() { - if (string.IsNullOrEmpty(TezosManager.Instance.Config.PinataApiKey)) + var pinataToken = ConfigGetter.GetOrCreateConfig().PinataApiToken; + if (string.IsNullOrEmpty(pinataToken)) { Logger.LogError("Can not proceed without Pinata API key."); return; } - var uploader = UploaderFactory.GetPinataUploader(TezosManager.Instance.Config.PinataApiKey); + var uploader = UploaderFactory.GetPinataUploader(pinataToken); var uploadCoroutine = uploader.UploadFile(ipfsUrl => { @@ -309,36 +308,9 @@ public void HandleUploadClick() } ``` -For a complete example, see the [IPFSUpload tutorial scene](/unity/scenes#ipfsupload-scene). - -## Signing messages - -You can also use the connection to the user's wallet to prompt them to sign messages. -Signing a message proves that it came from a specific user's wallet because the wallet encrypts the message with the user's account's key. - -For example, this code prompts the user to sign the message "This message came from my account." -Then, the callback verifies that the signature is valid and that it came from the user's account: - -```csharp -string payload = "This message came from my account."; - -private void Start() -{ - // Subscribe to the wallet event - TezosManager.Instance.EventManager.PayloadSigned += OnPayloadSigned; - - TezosManager.Instance.Wallet.RequestSignPayload(SignPayloadType.micheline, payload); -} - -private void OnPayloadSigned(SignResult obj) -{ - // Result is true if the message is signed correctly - // And that it came from the currently-connected wallet - var result = TezosManager.Instance.Wallet.VerifySignedPayload(SignPayloadType.micheline, payload); +When this code runs, the UI opens a file selection window and prompts the user to select a file. - Debug.Log($"Payload verification response: {result}"); -} -``` + ## Changing the RPC node @@ -346,10 +318,8 @@ As described in [The RPC interface](/architecture/nodes#the-rpc-interface), Tezo By default, the SDK sends requests to a public RPC node that uses the Ghostnet test network, where you can test transactions without spending real tez. For more information about test networks, see [Testing on testnets](/developing/testnets). -If you need to change the RPC node that the SDK uses, such as if the default node is overloaded or if you are ready to send transactions to Mainnet, you can set the RPC node by creating an instance of the [TezosConfigSO scriptable object](/unity/reference/TezosConfigSO) and setting the node in the **Rpc Url Format** field, as in this picture: - -Adding the Pinata API key and the data provider to the TezosConfigSO object +If you need to change the RPC node that the SDK uses, such as if the default node is overloaded or if you are ready to send transactions to Mainnet, you can set the RPC node by editing the TezosConfig scriptable object at `Assets/Tezos/Resources/TezosConfig.asset` and setting the RPC URL in the **Rpc Url Format** field, as in this picture: -Then, drag this instance of the TezosConfigSO scriptable object to the Config field of the TezosManager prefab. +Adding the Pinata API key and the data provider to the TezosConfig object -For more examples of how to work with the SDK, see [Tutorial scenes](/unity/scenes). + diff --git a/docs/unity/reference.md b/docs/unity/reference.md index f2a0cf744..9278b2540 100644 --- a/docs/unity/reference.md +++ b/docs/unity/reference.md @@ -3,18 +3,12 @@ title: Unity SDK reference sidebar_label: Reference authors: Tim McMackin last_update: - date: 11 January 2024 + date: 6 November 2024 --- The Tezos Unity SDK provides several objects that your Unity project can use to work with Tezos. These pages provide reference for the most important of these objects: -- [API object](/unity/reference/API): Provides information about the Tezos blockchain, such as what tokens accounts or contracts control -- [DAppMetadata object](/unity/reference/DAppMetadata): Provides read-only properties that describe the project +- [TezosAPI object](/unity/reference/API): Provides methods for many Tezos-related tasks - [DataProviderConfigSO scriptable object](/unity/reference/DataProviderConfigSO): Sets the indexer to get information about Tezos from -- [EventManager object](/unity/reference/EventManager): Provides events that you can add listeners to, such as when users connect their wallets - [TezosConfigSO scriptable object](/unity/reference/TezosConfigSO): Stores information about connecting to Tezos, including the RPC node and Pinata API key to use -- [TokenContract object](/unity/reference/TokenContract): Provides a built-in FA2-compatible smart contract and convenience methods to work with it -- [Wallet object](/unity/reference/Wallet): Provides methods to connect to wallets and send transactions from the connected account - -The SDK also provides Unity prefabs that are prerequisites for the SDK; see [Prefabs](/unity/prefabs). diff --git a/docs/unity/reference/API.md b/docs/unity/reference/API.md index 0b6c325a9..8d91b1b5c 100644 --- a/docs/unity/reference/API.md +++ b/docs/unity/reference/API.md @@ -1,534 +1,329 @@ --- -title: Unity SDK API object -sidebar_label: API object +title: Unity SDK TezosAPI object +sidebar_label: TezosAPI object authors: Tim McMackin last_update: - date: 6 December 2023 + date: 5 December 2024 --- -The Unity SDK class `TezosSDK.Tezos.API.TezosAPI`, which is available at runtime as the `TezosManager.Instance.Tezos.API` object, provides information about the Tezos blockchain, such as what tokens accounts or contracts control. +The Unity SDK class `Tezos.API.TezosAPI` provides methods for many Tezos-related tasks, including connecting to wallets, sending transactions to Tezos, and getting information about about the Tezos blockchain, such as what tokens accounts or contracts control. ## Properties None. -## Methods +## Initialization methods -### `GetTezosBalance()` +### `WaitUntilSDKInitialized()` + +Waits until the SDK is fully initialized. +Use this method at startup before trying to connect to wallets or use other features of the SDK. ```csharp -IEnumerator GetTezosBalance(Action callback, string address); +public static async UniTask WaitUntilSDKInitialized() ``` -Returns the balance of the specified account address in mutez. +## Wallet connection methods -Example: +### `ConnectWallet()` -```csharp -public void RunGetTezosBalance() -{ - Debug.Log("Getting balance"); - var routine = TezosManager.Instance.Tezos.API.GetTezosBalance( - callback: HandleTezosBalance, - address: myAddress - ); - StartCoroutine(routine); -} +Sends a request to a user's wallet to connect a Beacon or WalletConnect wallet to the application. +To connect social wallets, use [`SocialLogIn()`](#sociallogin). -private void HandleTezosBalance(ulong balanceMutez) -{ - Debug.Log(balanceMutez/1000000); -} +```csharp +public static async UniTask ConnectWallet(WalletProviderData walletProviderData); ``` -### `ReadView()` +If a wallet is already connected, this method either throws an exception (if a social wallet is connected) or returns the current connection information (if a Beacon or WalletConnect wallet is connected). -```csharp -IEnumerator ReadView( - string contractAddress, - string entrypoint, - string input, - Action callback); -``` +This method triggers the `WalletConnected` or `WalletConnectionFailed` events, depending on whether the connection was successful or not. -Returns the response from a contract [view](/smart-contracts/views). -Note that the `input` parameter must be a Michelson-encoded object, as in the following example, which passes an integer and string parameter to the view: +When the `WalletType` field of the `WalletProviderData` parameter is set to `WalletType.BEACON`, this method automatically picks the correct way to connect to wallets: -Example: +- In WebGL applications, it uses the `TezosSDK.Beacon.BeaconConnectorWebGl` class to trigger the browser to connect to a wallet app in a browser plugin. +- In all other applications, it uses the `TezosSDK.Beacon.BeaconConnectorDotNet` class to generate a QR code to connect to a wallet app on a mobile device or use a "deep link" to connect to a wallet on the same mobile device that is running the application. -```csharp -public void RunReadView() -{ - var input = new MichelinePrim - { - Prim = PrimType.Pair, - Args = new List - { - new MichelineInt(2), - new MichelineString("hello") - } - }.ToJson(); - - var routine = TezosManager.Instance.Tezos.API.ReadView( - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - entrypoint: viewName, - input: input, - callback: HandleRunReadView - ); - StartCoroutine(routine); -} +When the `WalletType` field of the `WalletProviderData` parameter is set to `WalletType.WALLETCONNECT`, this method opens the WalletConnect SDK's popup window, which provides deep links and a QR code to connect EVM wallets. -public void HandleRunReadView(JsonElement viewResponse) -{ - Debug.Log(viewResponse); -} -``` +For more information about connecting to wallets, see [Connecting accounts](/unity/connecting-accounts). + + + +### `SocialLogIn()` -### `GetTokensForOwner()` +Initiates a social login session and returns information about the connection. ```csharp -IEnumerator GetTokensForOwner( - Action> callback, - string owner, - bool withMetadata, - long maxItems, - TokensForOwnerOrder orderBy); +public static async UniTask SocialLogIn(SocialProviderData socialProviderData); ``` -Gets the tokens that an account owns. +This method triggers the `SocialLoggedIn` event. -Example: +### `Disconnect()` -```csharp -public void RunGetTokensForOwner() -{ - var routine = TezosManager.Instance.Tezos.API.GetTokensForOwner( - callback: HandleTokenBalances, - owner: myAddress, - withMetadata: true, - maxItems: 10, - orderBy: new TokensForOwnerOrder.ByLastTimeAsc(0) - ); - StartCoroutine(routine); -} +Disconnects the currently connected wallet and returns true if a wallet was connected or false if no wallet was connected. -private void HandleTokenBalances(IEnumerable tokenBalances) -{ - List tokens = new List(tokenBalances); - foreach (var tb in tokens) - { - Debug.Log($"{tb.Balance} tokens on contract {tb.TokenContract.Address}"); - } -} +```csharp +public static async UniTask Disconnect() ``` -### `GetOwnersForToken()` +This method triggers the `WalletDisconnected` or `SocialLoggedOut` event, depending on the type of wallet connection. -```csharp -IEnumerator GetOwnersForToken( - Action> callback, - string contractAddress, - uint tokenId, - long maxItems, - OwnersForTokenOrder orderBy); -``` +## Wallet information methods -Gets the accounts that own the specified token. +### `IsConnected()` -Example: +Returns true if any kind of wallet is connected to the application and false if not. ```csharp -public void RunGetOwnersForToken() -{ - var routine = TezosManager.Instance.Tezos.API.GetOwnersForToken( - callback: HandleTokenOwners, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - tokenId: 0, - maxItems: 10, - orderBy: new OwnersForTokenOrder.ByLastTimeAsc(0) - ); - StartCoroutine(routine); -} - -private void HandleTokenOwners(IEnumerable tokenBalances) -{ - List tokens = new List(tokenBalances); - foreach (var tb in tokens) - { - Debug.Log($"{tb.Balance} tokens on contract {tb.TokenContract.Address}"); - } -} +public static bool IsConnected() ``` -### `GetOwnersForContract()` +This method returns true if a Beacon, WalletConnect, or social wallet is connected. +To check for Beacon and WalletConnect connections specifically, use [`IsWalletConnected()`](#iswalletconnected). +To check for social wallets specifically, use [`IsSocialLoggedIn()`](#issocialloggedin). + +### `GetConnectionAddress()` + +Returns the connected address or an empty string if no wallet is connected. ```csharp -IEnumerator GetOwnersForContract( - Action> callback, - string contractAddress, - long maxItems, - OwnersForContractOrder orderBy); +public static string GetConnectionAddress() ``` -Gets the accounts that own tokens on the specified contract. +### `IsWalletConnected()` -Example: +Returns true if a Beacon or WalletConnect wallet is connected. ```csharp -public void RunGetOwnersForContract() -{ - var routine = TezosManager.Instance.Tezos.API.GetOwnersForContract( - callback: HandleOwnersForContract, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - maxItems: 10, - orderBy: new OwnersForContractOrder.ByLastTimeAsc(0) - ); - StartCoroutine(routine); -} - -private void HandleOwnersForContract(IEnumerable tokenBalances) -{ - List tokens = new List(tokenBalances); - foreach (var tb in tokens) - { - Debug.Log($"{tb.Owner} owns {tb.Balance} tokens on contract {tb.TokenContract.Address}"); - } -} +public static bool IsWalletConnected() ``` -### `IsHolderOfContract()` +### `IsSocialLoggedIn()` + +Returns true if a social wallet is connected. ```csharp -IEnumerator IsHolderOfContract( - Action callback, - string wallet, - string contractAddress); +public static bool IsSocialLoggedIn() ``` -Returns true if the specified account owns any token in the specified contract. +### `GetWalletConnectionData()` -Example: +Retrieves information about the current wallet connection. ```csharp -public void GetIsHolderOfContract() -{ - var routine = TezosManager.Instance.Tezos.API.IsHolderOfContract( - callback: HandleIsHolderOfContract, - wallet: myAddress, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address - ); - StartCoroutine(routine); -} - -private void HandleIsHolderOfContract(bool response) -{ - Debug.Log(response); -} +public static WalletProviderData GetWalletConnectionData() ``` -### `IsHolderOfToken()` +### `GetSocialLoginData()` -```csharp -IEnumerator IsHolderOfToken( - Action callback, - string wallet, - string contractAddress, - uint tokenId); +Retrieves information about the current social wallet connection. + +```cshar +public static SocialProviderData GetSocialLoginData(); ``` -Returns true if the specified account owns the specified token in the specified contract. +### `GetWalletProvider()` -Example: +Returns the internal object that the SDK uses to represent the connection to Beacon and WalletConnect wallets. ```csharp -public void GetIsHolderOfToken() -{ - var routine = TezosManager.Instance.Tezos.API.IsHolderOfToken( - callback: HandleIsHolderOfToken, - wallet: myAddress, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - tokenId: 0 - ); - StartCoroutine(routine); -} - -private void HandleIsHolderOfToken(bool response) -{ - Debug.Log(response); -} +public static IWalletProvider GetWalletProvider() ``` -### `GetTokenMetadata()` +To use this method you must specify the type of wallet provider that the Unity application is using. + +Example for WebGL applications: ```csharp -IEnumerator GetTokenMetadata( - Action callback, - string contractAddress, - uint tokenId); +BeaconWebGLProvider walletProvider = TezosAPI.GetWalletProvider(); +Debug.Log(walletProvider.WalletType); ``` -Gets the metadata for the specified token. - -Example: +Example for mobile applications: ```csharp -public void RunGetTokenMetadata() -{ - var routine = TezosManager.Instance.Tezos.API.GetTokenMetadata( - callback: HandleGetTokenMetadata, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - tokenId: 0 - ); - StartCoroutine(routine); -} - -private void HandleGetTokenMetadata(JsonElement tokenMetadata) -{ - Debug.Log(tokenMetadata.GetProperty("name")); -} +BeaconMobileProvider walletProvider = TezosAPI.GetWalletProvider(); +Debug.Log(walletProvider.WalletType); ``` -### `GetContractMetadata()` +### `GetSocialProvider()` + +Returns the internal object that the SDK uses to represent the connection to social wallets. ```csharp -public IEnumerator GetContractMetadata( - Action callback, - string contractAddress); +public static ISocialLoginProvider GetSocialProvider() ``` -Gets the metadata for the specified contract. -Most contracts, including the built-in FA2 contract, do not have metadata. - Example: ```csharp -public void RunGetContractMetadata() -{ - var routine = TezosManager.Instance.Tezos.API.GetContractMetadata( - callback: HandleGetContractMetadata, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address - ); - StartCoroutine(routine); -} - -private void HandleGetContractMetadata(JsonElement contractMetadata) -{ - Debug.Log(contractMetadata); -} +KukaiMobileProvider walletProvider = TezosAPI.GetSocialProvider(); +Debug.Log(walletProvider.WalletType); ``` -### `GetTokensForContract()` +## Tezos information methods + +### `GetBalance()` + +Fetches the balance of the connected account in mutez, as a string. ```csharp -IEnumerator GetTokensForContract( - Action> callback, - string contractAddress, - bool withMetadata, - long maxItems, - TokensForContractOrder orderBy); +public static async UniTask GetBalance() ``` -Gets the tokens in a contract. - Example: ```csharp -public void RunGetTokensForContract() +public void RunGetBalance() { - timesCalled = 0; - var routine = TezosManager.Instance.Tezos.API.GetTokensForContract( - callback: HandleGetTokensForContract, - contractAddress: TezosManager.Instance.Tezos.TokenContract.Address, - withMetadata: true, - maxItems: 10, - orderBy: new TokensForContractOrder.ByLastTimeAsc(0) - ); - StartCoroutine(routine); -} - -private void HandleGetTokensForContract(IEnumerable tokenList) -{ - List tokens = new List(tokenList); - foreach (var tk in tokens) + try + { + var balance = ulong.Parse(await TezosAPI.GetBalance()); + float convertedBalance = balance / 1000000f; + Debug.Log($"Balance: {balance} tez"); + } + catch (Exception e) { - Debug.Log(tk.TokenId); + Debug.LogError($"Balance fetch error: {e.Message}"); } } ``` -The callback returns a list of tokens, but not all of the fields in the `Token` objects are populated by default. -You can populate the fields you want to retrieve by editing the `GetTokensForContract` method of the `TezosSDK.Tezos.API.TezosAPI` class. - -The methods in this class retrieves information about Tezos via the [TZKT](https://tzkt.io/) block explorer. -To change the information that the `GetTokensForContract` method retrieves, update the URL to add fields. +### `ReadView()` -The default URL looks like this: +Returns the response from a contract [view](/smart-contracts/views). ```csharp -var url = - $"tokens?contract={contractAddress}&select=contract,tokenId as token_id" + - $"{(withMetadata ? ",metadata as token_metadata" : "")},holdersCount as holders_count,id," + - $"lastTime as last_time&{sort}&limit={maxItems}"; +public static UniTask ReadView(string contractAddress, string entrypoint, string input) ``` -To get the total supply of each token type, add the `totalSupply` field to the URL, like this: - -```csharp -var url = - $"tokens?contract={contractAddress}&select=contract,tokenId as token_id" + - $"{(withMetadata ? ",metadata as token_metadata" : "")},holdersCount as holders_count,id," + - $"totalSupply as total_supply," + - $"lastTime as last_time&{sort}&limit={maxItems}"; -``` +Note that the `input` parameter must be a Michelson-encoded object, as in the following example, which passes a string parameter to the view: -Now when you run the `GetTokensForContract` method, the data passed to the callback includes the total supply of each token: +Example: ```csharp -private void HandleGetTokensForContract(IEnumerable tokenList) -{ - List tokens = new List(tokenList); - foreach (var tk in tokens) - { - Debug.Log($"Token ID {tk.TokenId} has total supply {tk.TotalSupply} among {tk.HoldersCount} holders"); - } -} +var result = await TezosAPI.ReadView("KT1K46vZTMEe8bnacFvFQfgHtNDKniEauRMJ", "simple", "\"String value\""); +Debug.Log("View response: " + result); ``` -For information about what fields you can add to this URL, see the [TZKT API reference](https://api.tzkt.io/). +### `GetTokens()` -### `GetOperationStatus()` +Returns the tokens for a given contract or account address as a list of `TokenData` objects. ```csharp -IEnumerator GetOperationStatus( - Action callback, - string operationHash); +public static UniTask GetTokens( + string address, + int limit = 100 +) ``` -Returns true if the specified operation was successful, false if it failed, or null (or HTTP 204) if it doesn't exist. - -Example: +This example gets information about the tokens in a contract: ```csharp -public void HandleTransfer() +var tokenList = await TezosAPI.GetTokens>("KT1HP6uMwf829cDgwynZJ4rDvjLCZmfYjja1", 5); +foreach (TokenData token in tokenList) { - TezosManager - .Instance - .Tezos - .TokenContract - .Transfer( - completedCallback: TransferCompleted, - destination: address.text, - tokenId: int.Parse(id.text), - amount: int.Parse(amount.text)); + Debug.Log($"Token ID: {token.TokenId} has {token.HoldersCount} owners"); } +``` -private void TransferCompleted(string txHash) -{ - Debug.Log($"Transfer complete with transaction hash {txHash}"); - var routine = TezosManager.Instance.Tezos.API.GetOperationStatus( - callback: HandleGetOperationStatus, - operationHash: txHash - ); - StartCoroutine(routine); -} +This example gets the tokens that a user account holds: -private void HandleGetOperationStatus(bool? result) +```csharp +var tokenList = await TezosAPI.GetTokens>("tz1QCVQinE8iVj1H2fckqx6oiM85CNJSK9Sx", 5); +foreach (TokenData token in tokenList) { - Debug.Log(result); + Debug.Log($"Contract: {token.Contract.Address} ID: {token.TokenId}"); } ``` -### `GetLatestBlockLevel()` +### `GetTokenMetadata()` + +Gets the metadata for the specified token. ```csharp -IEnumerator GetLatestBlockLevel( - Action callback); +public static UniTask GetTokenMetadata( + string contractAddress, + uint tokenId +); ``` -Returns the block level, or the number of blocks since the genesis block. +## Transaction methods -Example: +### `RequestOperation()` -```csharp -public void RunGetLatestBlockLevel() -{ - var routine = TezosManager.Instance.Tezos.API.GetLatestBlockLevel( - callback: HandleGetLatestBlockLevel - ); - StartCoroutine(routine); -} +Sends a Tezos transaction and returns an object with the hash of the transaction. -private void HandleGetLatestBlockLevel(int blockLevel) -{ - Debug.Log(blockLevel); -} +```csharp +public static async UniTask RequestOperation(OperationRequest operationRequest) ``` -### `GetAccountCounter()` +This method triggers the `OperationResulted` event. -```csharp -IEnumerator GetAccountCounter( - Action callback, - string address); -``` +For examples, see [Calling contracts](/unity/calling-contracts). -Returns the counter for implicit accounts, which is a unique number that you can use to ensure that transactions are not duplicated. +To send an Etherlink transaction, use the Reown SDK as described in [Calling Etherlink contracts](/unity/calling-contracts#calling-etherlink-contracts). -Example: +### `GetOperationStatus()` ```csharp -public void RunGetAccountCounter() -{ - var routine = TezosManager.Instance.Tezos.API.GetAccountCounter( - callback: HandleGetAccountCounter, - address: myAddress - ); - StartCoroutine(routine); -} - -private void HandleGetAccountCounter(int counter) -{ - Debug.Log(counter); -} +public static UniTask GetOperationStatus(string operationHash) ``` -### `GetOriginatedContractsForOwner()` +Returns true if the specified operation was successful, false if it failed, or null (or HTTP 204) if it doesn't exist. + +### `RequestSignPayload()` + +Prompts the connected wallet to sign a payload and returns the signed payload. ```csharp -IEnumerator GetOriginatedContractsForOwner( - Action> callback, - string creator, - string codeHash, - long maxItems, - OriginatedContractsForOwnerOrder orderBy); +public static async UniTask RequestSignPayload(SignPayloadRequest operationRequest) ``` -Gets the contracts that the specified account deployed (originated). -Optionally, you can pass the hash of a contract to return only contracts that match that hash. -For example, the hash of the contract in the [`TokenContract`](/unity/reference/TokenContract) object is in the `Resources/Contracts/FA2TokenContractCodeHash.txt` file. +This method triggers the `SigningResulted` event. Example: ```csharp -public void RunGetOriginatedContractsForOwner() +private async void Start() { - var routine = TezosManager.Instance.Tezos.API.GetOriginatedContractsForOwner( - callback: HandleGetOriginatedContractsForOwner, - creator: myAddress, - codeHash: "", - maxItems: 10, - orderBy: new OriginatedContractsForOwnerOrder.ByLastActivityTimeAsc(0) - - ); - StartCoroutine(routine); + TezosAPI.SigningResulted += SigningResulted; + + await TezosAPI.WaitUntilSDKInitialized(); } -private void HandleGetOriginatedContractsForOwner(IEnumerable contractList) +public async void SignPayloadClick() { - List contracts = new List(contractList); - foreach (var contract in contracts) + try + { + var payload = "Hello World!"; + var bytes = Encoding.UTF8.GetBytes(payload); + var hexPayload = BitConverter.ToString(bytes); + hexPayload = hexPayload.Replace("-", ""); + hexPayload = "05" + hexPayload; + var result = await TezosAPI.RequestSignPayload( + new SignPayloadRequest + { + Payload = hexPayload, + SigningType = SignPayloadType.MICHELINE + } + ); + Debug.Log($"Signature: {result.Signature}"); + } + catch (Exception e) { - Debug.Log(contract.Address); + Debug.Log($"{e.Message}"); + Debug.Log($"{e.StackTrace}"); } } + +public void SigningResulted(SignPayloadResponse response) +{ + Debug.Log("SigningResulted"); + Debug.Log(response); +} ``` diff --git a/docs/unity/reference/DAppMetadata.md b/docs/unity/reference/DAppMetadata.md deleted file mode 100644 index 6bb60fce2..000000000 --- a/docs/unity/reference/DAppMetadata.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Unity SDK DAppMetadata object -sidebar_label: DAppMetadata object -authors: Tim McMackin -last_update: - date: 6 December 2023 ---- - -The Unity SDK class `TezosSDK.Tezos.DAppMetadata`, which is available at runtime as the `TezosManager.Instance.Tezos.DAppMetadata` object, provides read-only properties that provide access to the values that you set on the `TezosManager` prefab in the Unity Editor. - -## Properties - -These properties are read-only: - -- `Name`: The name of the project, which is shown in wallet applications when users connect to the project -- `Url`: The home page of the project -- `Icon`: The URL to a favicon for the project -- `Description`: A description of the project - -## Methods - -None. diff --git a/docs/unity/reference/DataProviderConfigSO.md b/docs/unity/reference/DataProviderConfigSO.md index 8456f2a60..abe1184f8 100644 --- a/docs/unity/reference/DataProviderConfigSO.md +++ b/docs/unity/reference/DataProviderConfigSO.md @@ -2,22 +2,19 @@ title: DataProviderConfigSO scriptable object authors: Tim McMackin last_update: - date: 11 January 2024 + date: 21 November 2024 --- The DataProviderConfigSO scriptable object sets the indexer that the SDK uses to get information about Tezos, such as an account's token balances. -Some Tezos dApps use a custom indexer to provide specific information that they need. +In most cases you do not need to edit this object, but in some cases Tezos dApps use a custom indexer to provide specific information that they need. -To use this object, create an instance of it, put your information in its fields, and then drag this instance to the Data Provider Config field of the [TezosConfigSO scriptable object](/unity/reference/TezosConfigSO) object, as in this picture: - -Adding the Pinata API key and the data provider to the TezosConfigSO object +Setting the indexer in the DataProviderConfigSO object ## Properties - `Script`: The attached script that implements the object - `Network`: A variable that lets you select which network to use, such as Tezos Mainnet or the Ghostnet testnet - `Base Url Format`: The URL of the indexer to use; this value replaces the variable `{network}` with the value of the `Network` field -- `Request Timeout Seconds`: The time in seconds to wait for a response from the indexer - `Documentation Url`: A link to the API reference for the indexer For more information about indexers, see [Indexers](/developing/information/indexers). diff --git a/docs/unity/reference/EventManager.md b/docs/unity/reference/EventManager.md deleted file mode 100644 index e5e7cb125..000000000 --- a/docs/unity/reference/EventManager.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Unity SDK EventManager object -sidebar_label: EventManager object -authors: Tim McMackin -last_update: - date: 28 December 2023 ---- - -The Unity SDK class `TezosSDK.Beacon.WalletEventManager`, which is available at runtime as the `TezosManager.Instance.EventManager` object, provides events that you can add listeners to. - -These events are asynchronous. -For example, if your project makes multiple calls to smart contracts, the `ContractCallCompleted` event runs multiple times, not necessarily in the order that you called the contracts. - -## Example - -This code adds a listener for the `WalletConnected` and `WalletDisconnected` events: - -```csharp -private void Start() -{ - TezosManager.Instance.EventManager.WalletConnected += OnWalletConnected; - TezosManager.Instance.EventManager.WalletDisconnected += OnWalletDisconnected; -} - -private void OnWalletConnected(WalletInfo walletInfo) -{ - Debug.Log(walletInfo.Address); -} - -private void OnWalletDisconnected(WalletInfo walletInfo) -{ - Debug.Log(walletInfo.Address); - Debug.Log("Wallet disconnected."); -} -``` - -## Events - -### `public event Action WalletConnected` - -Runs when a wallet connects successfully. -Returns a `TezosSDK.Beacon.WalletInfo` object with information that includes the address of the connected account. - -### `public event Action WalletConnectionFailed` - -Runs when a connection to a wallet fails. -Returns a `TezosSDK.Beacon.ErrorInfo` object with an error message. - -### `public event Action WalletDisconnected` - -Runs when a wallet disconnects successfully. -Returns a `TezosSDK.Beacon.WalletInfo` object with information that includes the address of the connected account. - -### `public event Action ContractCallCompleted` - -Runs when a call to a smart contract is confirmed on the blockchain. -Returns a `TezosSDK.Beacon.OperationResult` object with the hash of the transaction. - -### `public event Action ContractCallFailed` - -Runs when a call to a smart contract fails. -Returns a `TezosSDK.Beacon.ErrorInfo` object with an error message. - -### `public event Action ContractCallInjected` - -Runs when a call to a smart contract is sent to Tezos but before it has been included in a block and confirmed. -Returns a `TezosSDK.Beacon.OperationResult` object with the hash of the transaction. - -### `public event Action HandshakeReceived` - -Runs when a handshake with a user's wallet application is received. -Returns a `TezosSDK.Beacon.HandshakeData` object with the data that applications need to connect to the wallet. - -### `public event Action PairingCompleted` - -Runs when the user's wallet is connected to the project but before the user has approved the connection in the wallet app. -Returns a `TezosSDK.Beacon.PairingDoneData` object with details about the pairing, such as the dApp's public key and the timestamp of pairing completion. - -### `public event Action PayloadSigned` - -Runs when the user signs a payload. -Returns a `TezosSDK.Beacon.PairingDoneData` object with the signed payload. - -### `public event void SDKInitialized` - -Runs when the SDK loads. diff --git a/docs/unity/reference/TezosConfigSO.md b/docs/unity/reference/TezosConfigSO.md index 465c3a04f..ccef54cf4 100644 --- a/docs/unity/reference/TezosConfigSO.md +++ b/docs/unity/reference/TezosConfigSO.md @@ -1,20 +1,21 @@ --- -title: TezosConfigSO scriptable object +title: TezosConfig scriptable object authors: Tim McMackin last_update: - date: 11 January 2024 + date: 6 November 2024 --- -The TezosConfigSO scriptable object sets the RPC node that the SDK sends Tezos transactions to. +The TezosConfig scriptable object sets the RPC node that the SDK sends Tezos transactions to. -To use this object, create an instance of it, put your information in its fields, and then drag this instance of the TezosConfigSO scriptable object to the Config field of the TezosManager prefab. +To use this object, create an instance of it, put your information in its fields, and then drag this instance of the TezosConfig scriptable object to the Config field of the TezosManager prefab. -Adding the Pinata API key and the data provider to the TezosConfigSO object +Adding the Pinata API key and the data provider to the TezosConfig object ## Properties - `Script`: The attached script that implements the object - `Network`: A variable that lets you select which network to use, such as Tezos Mainnet or the Ghostnet testnet + - `RPC Url Format`: The URL of the RPC node to use; this value replaces the variable `{network}` with the value of the `Network` field - `Request Timeout Seconds`: The time in seconds to wait for a response from the indexer - `Pinata Api Key`: The Pinata JWT (not the API key or secret key) to use to upload files and data to IPFS diff --git a/docs/unity/reference/TokenContract.md b/docs/unity/reference/TokenContract.md deleted file mode 100644 index 3a3a84046..000000000 --- a/docs/unity/reference/TokenContract.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Unity SDK TokenContract object -sidebar_label: TokenContract object -authors: Tim McMackin -last_update: - date: 6 December 2023 ---- - -The Unity SDK class `TezosSDK.Tezos.API.Models.TokenContract`, which is available at runtime as the `TezosManager.Instance.Tezos.TokenContract` object, provides a built-in FA2-compatible smart contract and convenience methods to work with it. - -For information about FA2 contracts and tokens, see [FA2 tokens](/architecture/tokens/FA2). - -The Michelson source code of the built-in contract is in the `Resources/Contracts` folder of the SDK. - -## Properties - -These properties are populated after you deploy the contract with the `Deploy()` method: - -- `Address`: The address of the deployed contract -- `TokensCount`: The total number of token types in the contract -- `LastActivityTime`: The timestamp of the last time tokens were minted or transferred - -## Entrypoints - -The built-in contract has the entrypoints that the FA2 standard requires and a few other entrypoints for the convenience of developers. - -- `transfer`: Transfers tokens from a source account to one or more destination accounts. -Its parameters are the address of the source account and a list of destination accounts, each with the token ID and amount to transfer. -For a simpler way to transfer tokens, see the [`Transfer()`](#transfer) method. - -- `mint`: Creates a token type and one or more tokens of that type. -Its parameters are the address of the owner of the new tokens, the amount of tokens to create, and the metadata for the token type. -This entrypoint can be called only by the current administrator account. -For a simpler way to create tokens, see the [`Mint()`](#mint) method. - -- `balance_of`: Sends information about an owner's token balance to another contract. -Its parameters are a callback contract that accepts a list of token IDs and the amount that the specified account owns. -For a simpler way to get information about token ownership, see the [`API.GetTokensForOwner()`](/unity/reference/API#gettokensforowner) method. - -- `update_operators`: Adds or removes operators for the specified token owners and token IDs. -Its parameters are a list of commands to add or remove operators for token owners and IDs. -For information about operators, see [Operators](/architecture/tokens/FA2#operators). - -- `set_administrator`: Changes the account that can mint tokens. -Its parameter is the address of the new administrator account. -This entrypoint can be called only by the current administrator account. - -- `set_metadata`: Creates or changes a metadata field in the specified contract's storage. -Its parameters are a key-value pair for the new or updated metadata value. -This metadata is a value in the contract's storage, which is different from the metadata returned by the [`API.GetContractMetadata()`](/unity/reference/API#getcontractmetadata) method. -This entrypoint can be called only by the current administrator account. - -- `set_pause`: Sets the value of the `paused` storage field. -When this field is set to true, tokens can be minted but not transferred between accounts. -This entrypoint can be called only by the current administrator account. - -For examples of calling these entrypoints, see [Calling the built-in contract](/unity/managing-contracts#calling-contracts). - -### Constructors - -```csharp -new TokenContract(); -``` - -This constructor is for internal use. -To deploy the built-in contract, use the `Deploy()` method. - -```csharp -new TokenContract(string address); -``` - -Initializes a `TokenContract` object with a copy of the built-in contract that you have deployed already. - -To deploy the built-in contract, use the [`Deploy()`](#deploy) method. - -### `Deploy()` - -```csharp -void Deploy(Action completedCallback) -``` - -Deploys (originates) a contract based on the built-in contract, including prompting the connected wallet to pay the origination fees. - -The SDK stores the address of the contract with the Unity [PlayerPrefs](https://docs.unity3d.com/ScriptReference/PlayerPrefs.html). - -Parameters: - -- `completedCallback`: A callback method to run when the contract is deployed, which receives the address of the new contract - -Example: - -```csharp -public void HandleDeploy() -{ - TezosManager.Instance.Tezos.TokenContract.Deploy(OnContractDeployed); -} - -private void OnContractDeployed(string contractAddress) -{ - Debug.Log(contractAddress); -} -``` - -### `Mint()` - -```csharp -void Mint( - Action completedCallback, - TokenMetadata tokenMetadata, - string destination, - int amount) -``` - -Calls the `Mint` entrypoint of the contract to create a token type and mint tokens. - -Parameters: - -- `completedCallback`: A callback method to run when the token is minted, which receives a `TokenBalance` object with information about the new token -- `tokenMetadata`: A `TokenMetadata` object with information about the new token -- `destination`: The account that owns the new token, which can be a user account or a smart contract account -- `amount`: The number of tokens of the new type to create - -Example: - -```csharp -var initialOwner = TezosManager - .Instance - .Wallet - .GetWalletAddress(); - -const string imageAddress = "ipfs://QmX4t8ikQgjvLdqTtL51v6iVun9tNE7y7Txiw4piGQVNgK"; - -var tokenMetadata = new TokenMetadata -{ - Name = "My token", - Description = "Description for my token", - Symbol = "MYTOKEN", - Decimals = "0", - DisplayUri = imageAddress, - ArtifactUri = imageAddress, - ThumbnailUri = imageAddress -}; - -TezosManager - .Instance - .Tezos - .TokenContract - .Mint( - completedCallback: OnTokenMinted, - tokenMetadata: tokenMetadata, - destination: initialOwner, - amount: 100); - -private void OnTokenMinted(TokenBalance tokenBalance) -{ - Debug.Log($"Successfully minted token with Token ID {tokenBalance.TokenId}"); -} -``` - -### `Transfer()` - -```csharp -void Transfer( - Action completedCallback, - string destination, - int tokenId, - int amount) -``` - -Transfers tokens from the currently connected account to the destination account. - -Parameters: - -- `completedCallback`: A callback method to run when the token is minted, which receives the hash of the transfer transaction -- `destination`: The account to send the token to, which can be a user account or a smart contract account -- `tokenId`: The ID of the token to transfer -- `amount`: The number of tokens to transfer - -Example: - -```csharp -public void HandleTransfer() -{ - TezosManager - .Instance - .Tezos - .TokenContract - .Transfer( - completedCallback: TransferCompleted, - destination: address.text, - tokenId: int.Parse(id.text), - amount: int.Parse(amount.text)); -} - -private void TransferCompleted(string txHash) -{ - Logger.LogDebug($"Transfer complete with transaction hash {txHash}"); -} -``` diff --git a/docs/unity/reference/Wallet.md b/docs/unity/reference/Wallet.md deleted file mode 100644 index 59b62c70b..000000000 --- a/docs/unity/reference/Wallet.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Unity SDK Wallet object -sidebar_label: Wallet object -authors: Tim McMackin -last_update: - date: 28 December 2023 ---- - -The Unity SDK class `TezosSDK.Tezos.Wallet.WalletProvider`, which is available at runtime as `TezosManager.Instance.Wallet`, provides methods to connect to wallets and send transactions from the connected account. - -## Properties - -### `IsConnected` - -Returns true if a wallet is currently connected. - -### `HandshakeData` - -An object with a field named `PairingData` with the data that applications need to connect to the wallet. - -## Methods - -### `Connect()` - -```csharp -void Connect(WalletProviderType walletProvider, bool withRedirectToWallet) -``` - -Sends a request to a user's wallet to connect to the application. - -Parameters: - - - `walletProvider`: The type of wallet to connect to, including `WalletProviderType.beacon` for TZIP-10 wallets (most Tezos wallets) and `WalletProviderType.kukai` for Kukai wallets. - - `withRedirectToWallet`: When running on a mobile platform, whether to open the connected mobile app after connecting to a wallet. - -This method triggers the `WalletConnected` or `WalletConnectionFailed` events, depending on whether the connection was successful or not. - -When the `walletProvider` parameter is set to `WalletProviderType.beacon`, this method automatically picks the correct way to connect to wallets: - -- In WebGL applications, it uses the `TezosSDK.Beacon.BeaconConnectorWebGl` class to trigger the browser to connect to a wallet app in a browser plugin. -- In all other applications, it uses the `TezosSDK.Beacon.BeaconConnectorDotNet` class to generate a QR code to connect to a wallet app on a mobile device or use a "deep link" to connect to a wallet on the same mobile device that is running the application. - -When the `walletProvider` parameter is set to `WalletProviderType.kukai` in a WebGL application, it triggers the web browser to open the user's Kukai wallet. -This type of connection is appropriate only for WebGL applications. - - - -### `Disconnect()` - -```csharp -void Disconnect() -``` - -Disconnects from the currently connected wallet. - -This method triggers the `WalletDisconnected` event. - -### `GetWalletAddress()` - -```csharp -void GetWalletAddress() -``` - -Returns the address (public key hash) of the currently connected account, or NULL if no wallet is connected. - -### `RequestSignPayload()` - -```csharp -public void RequestSignPayload( - SignPayloadType signingType, - string payload) -``` - -Sends a request to the connected wallet to sign a payload string. - -Parameters: - - - `signingType`: The type of payload, such as raw, operation or micheline. - - `payload`: The payload to send to the wallet to sign. - - - -Signing a message proves that it came from a specific user's wallet because the wallet encrypts the message with the user's account's key. -For example, this code prompts the user to sign the message "This message came from my account." - -```csharp -string payload = "This message came from my account."; - -TezosManager.Instance.EventManager.PayloadSigned += OnPayloadSigned; -TezosManager.Instance.Wallet.RequestSignPayload(SignPayloadType.micheline, payload); -``` - -### `VerifySignedPayload()` - -```csharp -bool VerifySignedPayload(SignPayloadType signingType, string payload) -``` - -Returns true if most recent response to `RequestSignPayload` matches the specified payload and is properly signed. - -### `CallContract()` - -```csharp -void CallContract( - string contractAddress, - string entryPoint, - string input, - ulong amount = 0); -``` - -Calls the specified entrypoint of the specified contract. - -This method triggers the `ContractCallInjected` event if the call is successfully sent to Tezos. -Then it triggers `ContractCallCompleted` or `ContractCallFailed` events, depending on whether the call succeeded or failed. - - - -### `OriginateContract()` - -```csharp -void OriginateContract( - string script, - string delegateAddress); -``` - -Deploys (originates) the specified contract. - -To use this method, you must compile a contract to Michelson in a JSON file. -For an example, see the code of the built-in contract in `Resources/Contracts`. - -The optional `delegateAddress` parameter is the address of the account to delegate the contract's tez to. -For more information, see [Delegation](/smart-contracts/delegation). - -This method triggers the `ContractCallInjected` event if the call is successfully sent to Tezos. -Then it triggers `ContractCallCompleted` or `ContractCallFailed` events, depending on whether the origination operation succeeded or failed. diff --git a/docs/unity/reference/events.md b/docs/unity/reference/events.md new file mode 100644 index 000000000..08835842c --- /dev/null +++ b/docs/unity/reference/events.md @@ -0,0 +1,67 @@ +--- +title: Unity SDK events +sidebar_label: Events +authors: Tim McMackin +last_update: + date: 8 January 2025 +--- + +The Tezos Unity SDK uses events that you can add listeners to. +These events are asynchronous, which means that the order in which events are called is not guaranteed. + +For example, this code assigns functions to the `WalletConnected` and `WalletDisconnected` events to run when a Beacon or WalletConnect wallet connects or disconnects: + +```csharp +private async void Start() +{ + + TezosAPI.WalletConnected += OnWalletConnected; + TezosAPI.WalletDisconnected += OnWalletDisconnected; + + await TezosAPI.WaitUntilSDKInitialized(); +} + +private void OnWalletConnected(WalletProviderData walletProviderData) +{ + Debug.Log(walletProviderData.WalletType); + Debug.Log(walletProviderData.WalletAddress); + Debug.Log(walletProviderData.PublicKey); + Debug.Log(walletProviderData.PairingUri); +} + +private void OnWalletDisconnected() +{ + Debug.Log("Wallet disconnected."); +} +``` + +## `WalletConnected` + +Runs when a non-social wallet connects and returns an object with the type of wallet (`BEACON` or `WALLETCONNECT`), the address (public key hash) of the connected account, the public key, and the URI used for pairing with the wallet. + +## `WalletDisconnected` + +Runs when a non-social wallet disconnects. + +## `SocialLoggedIn` + +Runs when a social wallet connects and returns an object with the type of wallet (always `KUKAI`) and other information about the connection. + + +## `SocialLoggedOut` + +Runs when a social wallet disconnects. + +## `OperationResulted` + +Runs when a Tezos operation succeeds or fails and returns an object that includes the hash of the transaction. +This event does not run for Etherlink operations. + +## `SigningResulted` + +Runs when a user signs a payload and returns the signed payload. + +## `PairingRequested` + +Runs when the SDK attempts to pair with a Beacon wallet on a non-WebGL platform and returns the pairing information that the application can use to generate a QR code. +In most cases the application should use the Beacon popup window instead of generating the QR code itself. diff --git a/docs/unity/sample-game.md b/docs/unity/sample-game.md index 64ff6efe6..4bcf0d42c 100644 --- a/docs/unity/sample-game.md +++ b/docs/unity/sample-game.md @@ -51,7 +51,6 @@ The Unity application calls it from the `Assets/Scripts/Api/GameApi.cs` file for - The **smart contract** is a program that runs on the Tezos blockchain to manage tokens that represent in-game items. It maintains a ledger of tokens and owners and allows the backend's administrator account to transfer them to players. -The sample game uses a custom contract, but you can use the SDK's built-in FA2-compliant contract; see [Managing contracts](/unity/managing-contracts). You can view and interact with the contract on a block explorer, such as tzkt.io: https://tzkt.io/KT1TSZfPJ5uZW1GjcnXmvt1npAQ2nh5S1FAj/operations. - The **Interplanetary File System (IPFS)** stores metadata for the tokens, including pictures and descriptions. @@ -128,7 +127,7 @@ The [`UserDataManager.cs`](https://github.com/baking-bad/tezos-unity-game/blob/m Some of this information (such as the tokens that the player owns) comes from Tezos and other information (such as the player's statistics) comes from the backend. Information about the current game session and pending rewards are non-persistent data that are stored by the Unity application. -The `UserDataManager` class responds to [events](/unity/reference/EventManager) such as when the user connects their wallet and then loads information from the backend and from Tezos directly. +The `UserDataManager` class responds to [events](/unity/reference/events) such as when the user connects their wallet and then loads information from the backend and from Tezos directly. ## Opening the sample game diff --git a/docs/unity/scenes.md b/docs/unity/scenes.md index 8fead719f..fb44171b5 100644 --- a/docs/unity/scenes.md +++ b/docs/unity/scenes.md @@ -3,7 +3,7 @@ title: Unity SDK tutorial scenes sidebar_label: Tutorial scenes authors: Tim McMackin last_update: - date: 11 January 2024 + date: 4 November 2024 --- The SDK includes tutorial scenes that demonstrate how to use the SDK. @@ -97,7 +97,7 @@ This picture of the Wallet Connection scene in WebGL mode shows the deep link an The start of the WalletConnection scene, with no account information, showing deep link and social connection buttons -These UI elements call the [`Wallet.Connect()`](/unity/reference/Wallet#connect) method with the `walletProvider` parameter set to `WalletProviderType.beacon` for the direct links or QR code connections and the `walletProvider` parameter set to `WalletProviderType.kukai` for the social wallet connections. +These UI elements call the `Wallet.Connect()` method with the `walletProvider` parameter set to `WalletProviderType.beacon` for the direct links or QR code connections and the `walletProvider` parameter set to `WalletProviderType.kukai` for the social wallet connections. After the user approves the connection in the wallet, the scene shows the address of the connected account and its balance, as in the following picture. At the bottom of the scene there is a logout button that closes the connection. @@ -115,7 +115,7 @@ In this case, the smart contract keeps track of tokens, their metadata, and who The SDK comes with a sample smart contract that allows a Unity project to create tokens. You can customize these tokens, give them to users, and treat them like the players' in-game inventories. The Michelson source code of the built-in contract is in the `Resources/Contracts` folder of the SDK, but it isn't very human-readable. -For a list of the entrypoints in the contract, see [TokenContract object](/unity/reference/TokenContract). +For a list of the entrypoints in the contract, see TokenContract object. For an example of a deployed contract, see https://ghostnet.tzkt.io/KT1Nhr9Bmhy7kcUmezRxbbDybh5buNnrVLTY/entrypoints. Like the Wallet Connection scene, you must first connect to a wallet. @@ -125,7 +125,7 @@ When you click "Deploy Contract," your connected wallet prompts you to confirm t Because you are connected to the test network, these are worthless testnet tokens and not real currency. This process can take some time. -The scene calls the [`TokenContract.Deploy()`](/unity/reference/TokenContract#deploy) method to deploy the contract to Tezos. +The scene calls the `TokenContract.Deploy()` method to deploy the contract to Tezos. When you confirm the transaction in the wallet app, you must wait for the contract to be deployed on Tezos. The log in the Console panel shows a message that looks like `Received operation with hash oopFjLYGTbZTEFsTh4p1YPnHR1Up1SNnvE5xk2SRaGH6PZ4ry56`, which is the address of the Tezos transaction that deployed the contract. @@ -159,7 +159,7 @@ Because the contract follows the FA2 standard for tokens, the block explorer als The tokens that this scene creates have randomly generated metadata. To change the metadata, open the `TezosSDK/Examples/Contract/Scripts/MintToken.cs` file. -The file's `HandleMint` function creates the token by generating random numbers, creating a metadata object for the token, and using the [`TokenContract.Mint()`](/unity/reference/TokenContract#mint) method to send the mint transaction to the contract: +The file's `HandleMint` function creates the token by generating random numbers, creating a metadata object for the token, and using the `TokenContract.Mint()` method to send the mint transaction to the contract: ```csharp public void HandleMint() @@ -196,7 +196,7 @@ For example, this entry shows that the account that ends in `2zD` owns 9 of the The block explorer's Storage tab, showing the account address and the quantity of a token it owns -The transfer tutorial scene uses the [`TokenContract.Transfer()`](/unity/reference/TokenContract#transfer) method to transfer the token: +The transfer tutorial scene uses the `TokenContract.Transfer()`method to transfer the token: ```csharp public void HandleTransfer() diff --git a/docs/unity/upgrading.md b/docs/unity/upgrading.md new file mode 100644 index 000000000..3464dd4ce --- /dev/null +++ b/docs/unity/upgrading.md @@ -0,0 +1,68 @@ +--- +title: Upgrading the Unity SDK +sidebar_label: Upgrading +authors: Tim McMackin +last_update: + date: 25 November 2024 +--- + +Version 4.0.0 of the Unity SDK includes breaking changes from the previous version. + +## Changed methods + +These methods have changed in version 4.0.0: + +### Connecting to wallets + +Unity applications no longer use the `TezosSDK.Tezos.Wallet.WalletProvider` object to connect to wallets. +See [Connecting accounts](/unity/connecting-accounts). + +### Getting wallet information + +Unity applications no longer use the `TezosSDK.Tezos.Wallet.WalletProvider` object to get information about the connected wallet. + +Instead, use these methods: + +- `TezosAPI.GetConnectionAddress()`: Returns the address of the currently connected account +- `TezosAPI.GetBalance()`: Returns the balance of the connected account in tez (for Tezos connections) or XTZ (for Etherlink connections) +- `TezosAPI.GetWalletConnectionData()` or `TezosAPI.GetSocialLoginData()`: Returns information about the connected wallet + +### Signing messages + +The way that the SDK handles signing messages has changed. +For an example, see [Signing messages](/unity/quickstart#signing-messages). + +## Contracts + +Version 3 included a built-in FA2 token contract and convenience methods for using it. +This contract and the convenience methods are not provided in version 4, so you must deploy your own contract and call it directly, without the convenience methods. +The `TezosSDK.Tezos.API.Models.TokenContract` object is no longer available. + +The contract itself is still supported, so if you have a copy of the contract deployed, you can continue to use it. + +If you need an FA2 contract to manage tokens, templates are available in the [SmartPy](https://smartpy.io/ide) and [LIGO online IDE](https://ide.ligolang.org/). + +### Deploying contracts + +The `TokenContract.Deploy()` method and the `TokenContract.address` variable are not available in version 4.0.0. + +In most cases, you deploy a contract from another client and use that contract through the Unity SDK. +See [Deploying smart contracts](/smart-contracts/deploying). + +However, if you want to deploy a contract from the Unity SDK, you can use the `TezosAPI.DeployContract` method. + +### Calling contracts + +Version 4.0.0 of the SDK does not include the `TezosManager.Instance.Tezos.TokenContract.Mint()` method or the `TezosManager.Instance.Tezos.TokenContract.Transfer()` method. + +To call contracts with the SDK, see [Calling contracts with the Unity SDK](/unity/calling-contracts). + +### Managing tokens + +The SDK no longer includes convenience methods for getting token balances or transferring tokens. +To work with tokens, see [Managing tokens](/unity/managing-tokens). + +## Changing the RPC node + +It's easier to change the RPC node in version 4.0.0 because you can edit the TezosConfig scriptable object directly at `Assets/Tezos/Resources/TezosConfig.asset` and set the RPC URL in the **Rpc Url Format** field. +See [Changing the RPC node](/unity/quickstart#changing-the-rpc-node). diff --git a/sidebars.js b/sidebars.js index 051eccd47..a20a95810 100644 --- a/sidebars.js +++ b/sidebars.js @@ -214,11 +214,9 @@ const sidebars = { }, items: [ 'unity/quickstart', - 'unity/scenes', 'unity/sample-game', - 'unity/prefabs', 'unity/connecting-accounts', - 'unity/managing-contracts', + 'unity/calling-contracts', 'unity/managing-tokens', { type: 'category', @@ -229,12 +227,9 @@ const sidebars = { }, items: [ 'unity/reference/API', - 'unity/reference/DAppMetadata', + 'unity/reference/events', 'unity/reference/DataProviderConfigSO', - 'unity/reference/EventManager', 'unity/reference/TezosConfigSO', - 'unity/reference/TokenContract', - 'unity/reference/Wallet', ], }, ], diff --git a/src/scripts/check-links.js b/src/scripts/check-links.js new file mode 100644 index 000000000..854a7d4c1 --- /dev/null +++ b/src/scripts/check-links.js @@ -0,0 +1,20 @@ +const checkLinks = require('check-links') + +// results['https://foo.com'] // { status: 'alive', statusCode: 200 } +// results['https://404.com'] // { status: 'dead', statusCode: 404 } + +// example using a custom concurrency, timeout, and retry count +// const results2 = await checkLinks(['https://foo.com', 'https://404.com'], { +// concurrency: 1, +// timeout: { request: 30000 }, +// retry: { limit: 1 } +// }) + +async function check() { + + const results = await checkLinks(['https://docs.tezos.com']) + + console.log(JSON.stringify(results, null, 2)) +} + +check() \ No newline at end of file diff --git a/static/img/unity/kukai-sample-server.png b/static/img/unity/kukai-sample-server.png new file mode 100644 index 000000000..935c489d1 Binary files /dev/null and b/static/img/unity/kukai-sample-server.png differ diff --git a/static/img/unity/kukai-test-url.png b/static/img/unity/kukai-test-url.png new file mode 100644 index 000000000..7cf966a98 Binary files /dev/null and b/static/img/unity/kukai-test-url.png differ diff --git a/static/img/unity/kukai-trigger-deep-link.png b/static/img/unity/kukai-trigger-deep-link.png new file mode 100644 index 000000000..011b3f31b Binary files /dev/null and b/static/img/unity/kukai-trigger-deep-link.png differ diff --git a/static/img/unity/tzkt-balance-view.png b/static/img/unity/tzkt-balance-view.png new file mode 100644 index 000000000..54105f876 Binary files /dev/null and b/static/img/unity/tzkt-balance-view.png differ diff --git a/static/img/unity/unity-data-provider-config.png b/static/img/unity/unity-data-provider-config.png new file mode 100644 index 000000000..6a511195a Binary files /dev/null and b/static/img/unity/unity-data-provider-config.png differ diff --git a/static/img/unity/unity-inspector-tezosmanager.png b/static/img/unity/unity-inspector-tezosmanager.png deleted file mode 100644 index 21bf3b725..000000000 Binary files a/static/img/unity/unity-inspector-tezosmanager.png and /dev/null differ diff --git a/static/img/unity/unity-ipfs-scene-config.png b/static/img/unity/unity-ipfs-scene-config.png index a45e49d60..2a16d5e8b 100644 Binary files a/static/img/unity/unity-ipfs-scene-config.png and b/static/img/unity/unity-ipfs-scene-config.png differ diff --git a/static/img/unity/unity-quickstart-bind-rawimage.png b/static/img/unity/unity-quickstart-bind-rawimage.png new file mode 100644 index 000000000..dbe31939d Binary files /dev/null and b/static/img/unity/unity-quickstart-bind-rawimage.png differ diff --git a/static/img/unity/unity-quickstart-scripts-beacon.png b/static/img/unity/unity-quickstart-scripts-beacon.png new file mode 100644 index 000000000..fa4797b8d Binary files /dev/null and b/static/img/unity/unity-quickstart-scripts-beacon.png differ diff --git a/static/img/unity/unity-scene-layout-beacon.png b/static/img/unity/unity-scene-layout-beacon.png new file mode 100644 index 000000000..30a2629ae Binary files /dev/null and b/static/img/unity/unity-scene-layout-beacon.png differ diff --git a/static/img/unity/unity-scene-layout-walletconnect.png b/static/img/unity/unity-scene-layout-walletconnect.png new file mode 100644 index 000000000..4381bcd38 Binary files /dev/null and b/static/img/unity/unity-scene-layout-walletconnect.png differ diff --git a/static/img/unity/unity-scripts-walletconnect.png b/static/img/unity/unity-scripts-walletconnect.png new file mode 100644 index 000000000..d5bf99eed Binary files /dev/null and b/static/img/unity/unity-scripts-walletconnect.png differ diff --git a/static/img/unity/unity-walletconnect-config.png b/static/img/unity/unity-walletconnect-config.png new file mode 100644 index 000000000..c115a8674 Binary files /dev/null and b/static/img/unity/unity-walletconnect-config.png differ diff --git a/static/img/unity/unity-webgl-template.png b/static/img/unity/unity-webgl-template.png deleted file mode 100644 index f2224a186..000000000 Binary files a/static/img/unity/unity-webgl-template.png and /dev/null differ