diff --git a/Runtime/Scripts/API/TezosAPI.cs b/Runtime/Scripts/API/TezosAPI.cs index 269c6157..e6745ac1 100644 --- a/Runtime/Scripts/API/TezosAPI.cs +++ b/Runtime/Scripts/API/TezosAPI.cs @@ -161,8 +161,6 @@ await UnityMainThreadDispatcher.Instance().EnqueueAsync( return result; } - public static UniTask DeployContract(DeployContractRequest deployContractRequest) => ProviderFactory.GetConnectedProviderController().DeployContract(deployContractRequest); - /// /// Fetches the XTZ balance of a given wallet address asynchronously. /// @@ -173,155 +171,11 @@ public static UniTask GetBalance() return ProviderFactory.GetConnectedProviderController().GetBalance(); } - public static UniTask ReadView(string contractAddress, string view, string input) => _rpc.PostRequest(EndPoints.GetRunViewEndPoint(contractAddress, view), input); - - public static UniTask> GetTokensForOwner( - string owner, - bool withMetadata, - long maxItems, - TokensForOwnerOrder orderBy - ) - { - var sort = orderBy switch - { - TokensForOwnerOrder.Default byDefault => $"sort.asc=id&offset.cr={byDefault.lastId}", - TokensForOwnerOrder.ByLastTimeAsc byLastTimeAsc => - $"sort.asc=lastLevel&offset.pg={byLastTimeAsc.page}", - TokensForOwnerOrder.ByLastTimeDesc byLastTimeDesc => - $"sort.desc=lastLevel&offset.pg={byLastTimeDesc.page}", - _ => string.Empty - }; - return _rpc.GetRequest>( - EndPoints.GetTokensForOwnerEndPoint( - owner, withMetadata, - maxItems, sort - ) - ); - } - - public static UniTask> GetOwnersForToken( - string contractAddress, - uint tokenId, - long maxItems, - OwnersForTokenOrder orderBy - ) - { - var sort = orderBy switch - { - OwnersForTokenOrder.Default byDefault => $"sort.asc=id&offset.cr={byDefault.lastId}", - OwnersForTokenOrder.ByBalanceAsc byBalanceAsc => - $"sort.asc=balance&offset.pg={byBalanceAsc.page}", - OwnersForTokenOrder.ByBalanceDesc byBalanceDesc => - $"sort.desc=balance&offset.pg={byBalanceDesc.page}", - OwnersForTokenOrder.ByLastTimeAsc byLastTimeAsc => - $"sort.asc=lastLevel&offset.pg={byLastTimeAsc.page}", - OwnersForTokenOrder.ByLastTimeDesc byLastTimeDesc => - $"sort.desc=lastLevel&offset.pg={byLastTimeDesc.page}", - _ => string.Empty - }; - return _rpc.GetRequest>( - EndPoints.GetOwnersForTokenEndPoint( - contractAddress, - tokenId, maxItems, - sort - ) - ); - } - - public static UniTask> GetOwnersForContract( - string contractAddress, - long maxItems, - OwnersForContractOrder orderBy - ) - { - var sort = orderBy switch - { - OwnersForContractOrder.Default byDefault => $"sort.asc=id&offset.cr={byDefault.lastId}", - OwnersForContractOrder.ByLastTimeAsc byLastTimeAsc => - $"sort.asc=lastLevel&offset.pg={byLastTimeAsc.page}", - OwnersForContractOrder.ByLastTimeDesc byLastTimeDesc => - $"sort.desc=lastLevel&offset.pg={byLastTimeDesc.page}", - _ => string.Empty - }; - return _rpc.GetRequest>( - EndPoints.GetOwnersForContractEndPoint( - contractAddress, - maxItems, sort - ) - ); - } - - public static UniTask IsHolderOfContract(string wallet, string contractAddress) => _rpc.GetRequest(EndPoints.GetIsHolderOfContractEndPoint(wallet, contractAddress)); - - public static UniTask IsHolderOfToken(string wallet, string contractAddress, uint tokenId) => _rpc.GetRequest(EndPoints.GetIsHolderOfTokenEndPoint(wallet, contractAddress, tokenId)); - - public static UniTask GetTokenMetadata( - string contractAddress, - uint tokenId - ) => _rpc.GetRequest(EndPoints.GetTokenMetadataEndPoint(contractAddress, tokenId)); - - public static UniTask GetContractMetadata( - string contractAddress - ) => _rpc.GetRequest(EndPoints.GetContractMetadataEndPoint(contractAddress)); - - public static UniTask> GetTokensForContract( - string contractAddress, - bool withMetadata, - long maxItems, - TokensForContractOrder orderBy - ) - { - TezosLogger.LogDebug($"Getting tokens for contract: {contractAddress}"); - var sort = orderBy switch - { - TokensForContractOrder.Default byDefault => $"sort.asc=id&offset.cr={byDefault.lastId}", - TokensForContractOrder.ByLastTimeAsc byLastTimeAsc => - $"sort.asc=lastLevel&offset.pg={byLastTimeAsc.page}", - TokensForContractOrder.ByLastTimeDesc byLastTimeDesc => - $"sort.desc=lastLevel&offset.pg={byLastTimeDesc.page}", - TokensForContractOrder.ByHoldersCountAsc byHoldersCountAsc => - $"sort.asc=holdersCount&offset.pg={byHoldersCountAsc.page}", - TokensForContractOrder.ByHoldersCountDesc byHoldersCountDesc => - $"sort.desc=holdersCount&offset.pg={byHoldersCountDesc.page}", - _ => string.Empty - }; - return _rpc.GetRequest>( - EndPoints.GetTokensForContractEndPoint( - contractAddress, - withMetadata, - maxItems, sort - ) - ); - } - - public static UniTask GetOperationStatus(string operationHash) => _rpc.GetRequest(EndPoints.GetOperationStatusEndPoint(operationHash)); - - public static UniTask GetLatestBlockLevel() => _rpc.GetRequest(EndPoints.GetLatestBlockLevelEndPoint()); - - public static UniTask GetAccountCounter(string address) => _rpc.GetRequest(EndPoints.GetAccountCounterEndPoint(address)); - - public static UniTask> GetOriginatedContractsForOwner( - string creator, - string codeHash, - long maxItems, - OriginatedContractsForOwnerOrder orderBy - ) - { - TezosLogger.LogDebug($"API.GetOriginatedContractsForOwner: creator={creator}, codeHash={codeHash}"); - - var sort = orderBy switch - { - OriginatedContractsForOwnerOrder.Default byDefault => $"sort.asc=id&offset.cr={byDefault.lastId}", - OriginatedContractsForOwnerOrder.ByLastActivityTimeAsc byLastTimeAsc => $"sort.asc=lastActivity&offset.pg={byLastTimeAsc.page}", - OriginatedContractsForOwnerOrder.ByLastActivityTimeDesc byLastTimeDesc => $"sort.desc=lastActivity&offset.pg={byLastTimeDesc.page}", - _ => string.Empty - }; - - var url = $"contracts?creator={creator}&tzips.any=fa2&codeHash={codeHash}&" + - $"select=address,tokensCount as tokens_count,lastActivity,lastActivityTime as last_activity_time,id&{sort}&limit={maxItems}"; - - return _rpc.GetRequest>(url); - } + public static UniTask DeployContract(DeployContractRequest deployContractRequest) => ProviderFactory.GetConnectedProviderController().DeployContract(deployContractRequest); + public static UniTask ReadView(string contractAddress, string view, string input) => _rpc.PostRequest(EndPoints.GetRunViewEndPoint(contractAddress, view), input); + public static UniTask GetTokens(string address, int limit = 100) => _rpc.GetRequest(EndPoints.GetTokensEndPoint(address, limit)); + public static UniTask GetTokenMetadata(string tokenId) => _rpc.GetRequest(EndPoints.GetTokenMetadataEndPoint(tokenId)); + public static UniTask GetOperationStatus(string operationHash) => _rpc.GetRequest(EndPoints.GetOperationStatusEndPoint(operationHash)); #endregion } diff --git a/Runtime/Scripts/API/TokenAPI.cs b/Runtime/Scripts/API/TokenAPI.cs deleted file mode 100644 index f45bde31..00000000 --- a/Runtime/Scripts/API/TokenAPI.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Netezos.Contracts; -using Netezos.Encoding; -using Newtonsoft.Json.Linq; -using Tezos.Cysharp.Threading.Tasks; -using Tezos.Logger; -using Tezos.Operation; -using Tezos.Token; -using UnityEngine; -using OperationRequest = Tezos.Operation.OperationRequest; -using OperationResponse = Tezos.Operation.OperationResponse; - -namespace Tezos.API -{ - public static partial class TezosAPI - { - public static async UniTask Mint(TokenMetadata tokenMetadata, string destination, int amount, string address) - { - TezosLogger.LogDebug($"Minting {amount} tokens to {destination} with metadata {tokenMetadata}"); - - var tokens = (await GetTokensForContract(address, false, 10_000, new TokensForContractOrder.Default(0))).ToList(); - - TezosLogger.LogDebug("Got tokens for contract"); - var tokenId = tokens.Count; - const string entrypoint = "mint"; - - var mintParameters = GetContractScript().BuildParameter(entrypoint, new { address = destination, amount = amount.ToString(), metadata = tokenMetadata.GetMetadataDict(), token_id = tokenId.ToString() }).ToJson(); - - var walletOperationRequest = new OperationRequest { Destination = address, EntryPoint = entrypoint, Arg = mintParameters }; - var result = await RequestOperation(walletOperationRequest); - - TezosLogger.LogDebug($"Mint completed with operation ID: {result.Id}"); - - var owner = GetWalletConnectionData().WalletAddress; - - var getOwnerTokensCoroutine = await GetTokensForOwner(owner, true, 10_000, new TokensForOwnerOrder.Default(0)); - - return getOwnerTokensCoroutine.Last(); - } - - public static async UniTask Transfer(string destination, int tokenId, int amount) - { - var activeAddress = GetWalletConnectionData().WalletAddress; - const string entryPoint = "transfer"; - - var param = GetContractScript().BuildParameter(entryPoint, new List { new { from_ = activeAddress, txs = new List { new { to_ = destination, token_id = tokenId, amount } } } }).ToJson(); - - var walletOperationRequest = new OperationRequest { Destination = activeAddress, EntryPoint = entryPoint, Arg = param }; - - var result = await RequestOperation(walletOperationRequest); - - return result.TransactionHash; - } - - private static ContractScript GetContractScript() // TODO: This needs to be replaced with the actual contract script, not the conract we ship with the SDK. Netezos possibly has a way of achieving this. - { - var script = Resources.Load("Contracts/FA2TokenContract").text; - - if (string.IsNullOrEmpty(script)) - { - throw new InvalidOperationException("Failed to load contract script"); - } - - var code = JObject.Parse(script).SelectToken("code"); - - if (code != null) - { - return new ContractScript(Micheline.FromJson(code.ToString())!); - } - - throw new InvalidOperationException("Failed to parse contract code"); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/API/TokenAPI.cs.meta b/Runtime/Scripts/API/TokenAPI.cs.meta deleted file mode 100644 index 8403a97b..00000000 --- a/Runtime/Scripts/API/TokenAPI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5ae3ad1539e14f13933342fc1f522261 -timeCreated: 1727172648 \ No newline at end of file diff --git a/Runtime/Scripts/Request/EndPoints/EndPoints.cs b/Runtime/Scripts/Request/EndPoints/EndPoints.cs index b812b868..1e1dbb98 100644 --- a/Runtime/Scripts/Request/EndPoints/EndPoints.cs +++ b/Runtime/Scripts/Request/EndPoints/EndPoints.cs @@ -1,5 +1,5 @@ -using System; using System.IO; +using System.Web; using Tezos.Configs; using Tezos.MessageSystem; @@ -11,19 +11,27 @@ public static class EndPoints static EndPoints() => _baseUrl = ConfigGetter.GetOrCreateConfig().BaseUrl; - public static string GetBalanceEndPoint(string walletAddress) => Path.Combine(_baseUrl, "accounts", walletAddress, "balance"); - public static string GetContractCodeEndPoint(string contract) => Path.Combine(_baseUrl, $"chains/main/blocks/head/context/contracts/{contract}/script/"); - public static string GetRunViewEndPoint(string contract, string name) => Path.Combine(_baseUrl, $"helpers/view/{contract}/{name}"); - public static string GetIsHolderOfContractEndPoint(string wallet, string contractAddress) => Path.Combine(_baseUrl, $"tokens/balances?account={wallet}&token.contract={contractAddress}&balance.ne=0&select=id"); - public static string GetIsHolderOfTokenEndPoint(string wallet, string contractAddress, uint tokenId) => Path.Combine(_baseUrl, $"tokens/balances?account={wallet}&token.contract={contractAddress}&token.tokenId={tokenId}&balance.ne=0&select=id"); - public static string GetTokenMetadataEndPoint(string contractAddress, uint tokenId) => Path.Combine(_baseUrl, $"tokens?contract={contractAddress}&tokenId={tokenId}&select=metadata"); - public static string GetContractMetadataEndPoint(string contractAddress) => Path.Combine(_baseUrl, $"accounts/{contractAddress}?legacy=false"); - public static string GetOperationStatusEndPoint(string operationHash) => Path.Combine(_baseUrl, $"operations/{operationHash}/status"); - public static string GetLatestBlockLevelEndPoint() => Path.Combine(_baseUrl, $"blocks/{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ}/level"); - public static string GetAccountCounterEndPoint(string address) => Path.Combine(_baseUrl, $"accounts/{address}/counter"); - public static string GetTokensForOwnerEndPoint(string owner, bool withMetadata, long maxItems, string sort) => Path.Combine(_baseUrl, "tokens/balances?" + $"account={owner}&balance.ne=0&" + "select=account.address as owner,balance,token.contract as token_contract," + $"token.tokenId as token_id{(withMetadata ? ",token.metadata as token_metadata" : "")}," + "lastTime as last_time,id&" + $"{sort}&limit={maxItems}"); - public static string GetOwnersForTokenEndPoint(string contractAddress, uint tokenId, long maxItems, string sort) => Path.Combine(_baseUrl, "tokens/balances?" + $"token.contract={contractAddress}&balance.ne=0&token.tokenId={tokenId}&" + "select=account.address as owner,balance,token.contract as token_contract," + "token.tokenId as token_id,lastTime as last_time,id&" + $"{sort}&limit={maxItems}"); - public static string GetOwnersForContractEndPoint(string contractAddress, long maxItems, string sort) => Path.Combine(_baseUrl, "tokens/balances?" + $"token.contract={contractAddress}&balance.ne=0&" + "select=account.address as owner,balance,token.contract as token_contract," + "token.tokenId as token_id,id&" + $"{sort}&limit={maxItems}"); - public static string GetTokensForContractEndPoint(string contractAddress, bool withMetadata, long maxItems, string sort) => Path.Combine(_baseUrl, $"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 string GetBalanceEndPoint(string walletAddress) => Path.Combine(_baseUrl, "accounts", walletAddress, "balance"); + public static string GetRunViewEndPoint(string contract, string name) => Path.Combine(_baseUrl, $"helpers/view/{contract}/{name}"); + public static string GetOperationStatusEndPoint(string operationHash) => Path.Combine(_baseUrl, $"operations/{operationHash}/status"); + + public static string GetTokenMetadataEndPoint(string tokenId) + { + var url = Path.Combine(_baseUrl, "tokens"); + var queryParams = HttpUtility.ParseQueryString(string.Empty); + queryParams["tokenId"] = tokenId; + queryParams["limit"] = "1"; + queryParams["select"] = "metadata"; + return $"{url}?{queryParams}"; + } + + public static string GetTokensEndPoint(string address, int limit = 10) + { + var url = Path.Combine(_baseUrl, "tokens"); + var queryParams = HttpUtility.ParseQueryString(string.Empty); + queryParams["sender"] = address; + queryParams["limit"] = limit.ToString(); + return $"{url}?{queryParams}"; + } } } \ No newline at end of file diff --git a/Runtime/Scripts/Request/HttpClients/TezosClient.cs b/Runtime/Scripts/Request/HttpClients/TezosClient.cs index 616dc504..d87c984c 100644 --- a/Runtime/Scripts/Request/HttpClients/TezosClient.cs +++ b/Runtime/Scripts/Request/HttpClients/TezosClient.cs @@ -13,7 +13,7 @@ public class TezosClient private int RequestTimeout { get; } - private T DeserializeJson(string json) => JsonConvert.DeserializeObject(json); + private T DeserializeJson(string json) => JsonConvert.DeserializeObject(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }); public async UniTask GetRequest(string endpoint) { diff --git a/Runtime/Scripts/Token/TokenBalance.cs b/Runtime/Scripts/Token/TokenBalance.cs index 5b378d64..1d5a5f51 100644 --- a/Runtime/Scripts/Token/TokenBalance.cs +++ b/Runtime/Scripts/Token/TokenBalance.cs @@ -3,7 +3,6 @@ namespace Tezos.Token { - public class TokenBalance { /// @@ -37,12 +36,11 @@ public class TokenBalance /// /// Token metadata. /// - public JsonElement TokenMetadata { get; set; } + public TokenMetadata TokenMetadata { get; set; } /// /// Timestamp of the block where the token balance was last changed. /// public DateTime LastTime { get; set; } } - } \ No newline at end of file diff --git a/Runtime/Scripts/Token/TokenData.cs b/Runtime/Scripts/Token/TokenData.cs index bacf2c92..8c40c4c2 100644 --- a/Runtime/Scripts/Token/TokenData.cs +++ b/Runtime/Scripts/Token/TokenData.cs @@ -3,7 +3,6 @@ namespace Tezos.Token { - public class TokenData { /// @@ -91,7 +90,6 @@ public class TokenData /// /// Token metadata. /// - public JsonElement TokenMetadata { get; set; } + public TokenMetadata TokenMetadata { get; set; } } - } \ No newline at end of file diff --git a/Runtime/Scripts/WalletProvider/WalletProviderController.cs b/Runtime/Scripts/WalletProvider/WalletProviderController.cs index 8557958f..e4078343 100644 --- a/Runtime/Scripts/WalletProvider/WalletProviderController.cs +++ b/Runtime/Scripts/WalletProvider/WalletProviderController.cs @@ -90,9 +90,9 @@ public async UniTask Disconnect() return result; } - public UniTask GetBalance() => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).GetBalance(_connectedWalletData.WalletAddress); - public UniTask RequestOperation(OperationRequest walletOperationRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).RequestOperation(walletOperationRequest); - public UniTask RequestSignPayload(SignPayloadRequest walletSignPayloadRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).RequestSignPayload(walletSignPayloadRequest); - public UniTask DeployContract(DeployContractRequest walletDeployContractRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).DeployContract(walletDeployContractRequest); + public UniTask GetBalance() => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).GetBalance(_connectedWalletData.WalletAddress); + public UniTask RequestOperation(OperationRequest walletOperationRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).RequestOperation(walletOperationRequest); + public UniTask RequestSignPayload(SignPayloadRequest walletSignPayloadRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).RequestSignPayload(walletSignPayloadRequest); + public UniTask DeployContract(DeployContractRequest walletDeployContractRequest) => _walletProviders.Find(wp => wp.WalletType == _connectedWalletData?.WalletType).DeployContract(walletDeployContractRequest); } } \ No newline at end of file