From 83b1e0c7761751c35e6c05dce78e1067b17d7bd4 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Mon, 7 Oct 2024 16:34:41 +1300 Subject: [PATCH] feat: create and cancel 1155 orders --- .../Shared/Scripts/Model/ListingsResponse.cs | 7 ++ Assets/Shared/Scripts/UI/AssetDetailsView.cs | 99 +++++++++++++------ Assets/Shared/Scripts/UI/OrderDetailsView.cs | 10 +- Assets/Unity.Hypercasual.asmdef | 51 +++++----- Packages/packages-lock.json | 2 +- 5 files changed, 106 insertions(+), 63 deletions(-) diff --git a/Assets/Shared/Scripts/Model/ListingsResponse.cs b/Assets/Shared/Scripts/Model/ListingsResponse.cs index f4af5475..9d1a653e 100644 --- a/Assets/Shared/Scripts/Model/ListingsResponse.cs +++ b/Assets/Shared/Scripts/Model/ListingsResponse.cs @@ -21,6 +21,7 @@ public class OldListing public string id; public ListingStatus status; public List buy; + public List sell; } [Serializable] @@ -34,4 +35,10 @@ public class ListingBuy { public string amount; } + + [Serializable] + public class ListingSell + { + public string amount; + } } \ No newline at end of file diff --git a/Assets/Shared/Scripts/UI/AssetDetailsView.cs b/Assets/Shared/Scripts/UI/AssetDetailsView.cs index 90f63390..78f2bbd8 100644 --- a/Assets/Shared/Scripts/UI/AssetDetailsView.cs +++ b/Assets/Shared/Scripts/UI/AssetDetailsView.cs @@ -16,8 +16,6 @@ using Newtonsoft.Json; using TMPro; using UnityEngine; -using Action = Immutable.Orderbook.Model.Action; -using ApiException = Immutable.Search.Client.ApiException; namespace HyperCasual.Runner { @@ -62,9 +60,9 @@ public class AssetDetailsView : View public AssetDetailsView() { - var tsConfig = new Configuration(); - tsConfig.BasePath = Config.BASE_URL; - m_OrderbookApi = new OrderbookApi(tsConfig); + var orderbookConfig = new Configuration(); + orderbookConfig.BasePath = Config.BASE_URL; + m_OrderbookApi = new OrderbookApi(orderbookConfig); var searchConfig = new Immutable.Search.Client.Configuration(); searchConfig.BasePath = Config.BASE_URL; @@ -152,7 +150,12 @@ public async void Initialise(AssetModel asset) { var amount = m_Listing.buy[0].amount; var quantity = (decimal)BigInteger.Parse(amount) / (decimal)BigInteger.Pow(10, 18); - m_AmountText.text = $"{quantity} IMR"; + m_AmountText.text = m_Asset.contract_type switch + { + "ERC721" => $"{quantity} IMR", + "ERC1155" => $"{m_Listing.sell[0].amount} for {quantity} IMR", + _ => m_AmountText.text + }; } else { @@ -250,7 +253,7 @@ private async void GetMarketData() /// private async void OnSellButtonClicked() { - var (result, price) = await m_CustomDialog.ShowDialog( + var (priceResult, price) = await m_CustomDialog.ShowDialog( $"List {m_Asset.name} for sale", "Enter your price below (in IMR):", "Confirm", @@ -258,40 +261,63 @@ private async void OnSellButtonClicked() true ); - if (result) + if (!priceResult) return; + + var normalizedPrice = Math.Floor(decimal.Parse(price) * (decimal)BigInteger.Pow(10, 18)); + + var amountToSell = "1"; + if (m_Asset.contract_type == ERC1155Item.TypeEnum.ERC1155.ToString()) { - m_SellButton.gameObject.SetActive(false); - m_Progress.gameObject.SetActive(true); - var amount = Math.Floor(decimal.Parse(price) * (decimal)BigInteger.Pow(10, 18)); + var (amountResult, amount) = await m_CustomDialog.ShowDialog( + $"How many {m_Asset.name} do you want to sell?", + "Enter the amount below:", + "Confirm", + "Cancel", + true + ); - var listingId = await Sell($"{amount}"); - Debug.Log($"Sell complete: Listing ID: {listingId}"); + if (!amountResult) return; - m_SellButton.gameObject.SetActive(listingId == null); - m_CancelButton.gameObject.SetActive(listingId != null); - m_AmountText.text = listingId != null ? $"{price} IMR" : "Not listed"; - m_Progress.gameObject.SetActive(false); + amountToSell = amount; + } + + m_SellButton.gameObject.SetActive(false); + m_Progress.gameObject.SetActive(true); + + var listingId = await Sell($"{normalizedPrice}", amountToSell); + Debug.Log($"Sell complete: Listing ID: {listingId}"); + + m_SellButton.gameObject.SetActive(listingId == null); + m_CancelButton.gameObject.SetActive(listingId != null); + + if (listingId != null) + { + m_AmountText.text = m_Asset.contract_type switch + { + "ERC721" => $"{price} IMR", + "ERC1155" => $"{amountToSell} for {price} IMR", + _ => m_AmountText.text + }; + } + else + { + m_AmountText.text = "Not listed"; } + + m_Progress.gameObject.SetActive(false); } private async UniTask PrepareListing( - string nftTokenAddress, string tokenId, string price, string erc20TokenAddress) + string nftTokenAddress, string tokenId, string price, string erc20TokenAddress, string amountToSell) { + Debug.Log("Prepare listing..."); + // Create the NFT listing based on its contract type (ERC721 or ERC1155) var sell = m_Asset.contract_type switch { - var type when type == ERC1155Item.TypeEnum.ERC1155.ToString() => - (await m_CustomDialog.ShowDialog( - $"How many {m_Asset.name} do you want to sell?", - "Enter the amount below:", - "Confirm", - "Cancel", - true - )) is (true, var amount) - ? new PrepareListingRequestSell(new ERC1155Item(amount, nftTokenAddress, tokenId)) - : throw new Exception("Sale cancelled by user"), - + var type when type == ERC1155Item.TypeEnum.ERC1155.ToString() => + new PrepareListingRequestSell(new ERC1155Item(amountToSell, nftTokenAddress, tokenId)), var type when type == ERC721Item.TypeEnum.ERC721.ToString() => new PrepareListingRequestSell(new ERC721Item(nftTokenAddress, tokenId)), @@ -312,6 +338,8 @@ private async UniTask PrepareListing( private async UniTask SignAndSubmitApproval(PrepareListing200Response prepareListingResponse) { + Debug.Log("Sign and submit approval..."); + var transactionAction = prepareListingResponse.Actions.FirstOrDefault(action => action.ActualInstance.GetType() == typeof(TransactionAction)); @@ -333,6 +361,8 @@ private async UniTask SignAndSubmitApproval(PrepareListing200Response prepareLis private async UniTask SignListing(PrepareListing200Response prepareListingResponse) { + Debug.Log("Sign listing..."); + var signableAction = prepareListingResponse.Actions.FirstOrDefault(action => action.ActualInstance.GetType() == typeof(SignableAction)); @@ -349,13 +379,15 @@ private async UniTask SignListing(PrepareListing200Response prepareListi /// Prepares the listing for the asset. /// /// The price of the asset in smallest unit. + /// The amount to sell. This is only used for ERC1155 /// The listing ID is asset was successfully listed - private async UniTask Sell(string price) + private async UniTask Sell(string price, string amountToSell) { try { - PrepareListing200Response prepareListingResponse = - await PrepareListing(m_Asset.contract_address, m_Asset.token_id, $"{price}", Contract.TOKEN); + var prepareListingResponse = + await PrepareListing(m_Asset.contract_address, m_Asset.token_id, $"{price}", + Contract.TOKEN, amountToSell); await SignAndSubmitApproval(prepareListingResponse); @@ -371,6 +403,7 @@ private async UniTask SignListing(PrepareListing200Response prepareListi catch (ApiException e) { Debug.LogError($"API error: {e.Message} (Status Code: {e.ErrorCode})"); + Debug.LogError($"API error content: {e.ErrorContent}"); Debug.LogError(e.StackTrace); } catch (Exception ex) @@ -391,6 +424,8 @@ private async UniTask SignListing(PrepareListing200Response prepareListi private async UniTask ListAsset(string signature, PrepareListing200Response preparedListing) { + Debug.Log("List asset..."); + var createListingResponse = await m_OrderbookApi.CreateListingAsync( new CreateListingRequest ( diff --git a/Assets/Shared/Scripts/UI/OrderDetailsView.cs b/Assets/Shared/Scripts/UI/OrderDetailsView.cs index ac247aed..dc215183 100644 --- a/Assets/Shared/Scripts/UI/OrderDetailsView.cs +++ b/Assets/Shared/Scripts/UI/OrderDetailsView.cs @@ -36,16 +36,16 @@ public class OrderDetailsView : View private readonly List m_AttributeViews = new(); private readonly List m_ListingViews = new(); - private readonly OrderbookApi m_TsApi; + private readonly OrderbookApi m_OrderbookApi; private Listing m_Listing; private StackBundle m_Order; public OrderDetailsView() { - var tsConfig = new Configuration(); - tsConfig.BasePath = Config.BASE_URL; - m_TsApi = new OrderbookApi(tsConfig); + var orderbookConfig = new Configuration(); + orderbookConfig.BasePath = Config.BASE_URL; + m_OrderbookApi = new OrderbookApi(orderbookConfig); } private async void OnEnable() @@ -186,7 +186,7 @@ private async UniTask OnBuyButtonClick(Listing listing) takerAddress: SaveManager.Instance.WalletAddress, listingId: listing.ListingId, takerFees: fees); - var createListingResponse = await m_TsApi.FulfillOrderAsync(request); + var createListingResponse = await m_OrderbookApi.FulfillOrderAsync(request); if (createListingResponse.Actions.Count > 0) { diff --git a/Assets/Unity.Hypercasual.asmdef b/Assets/Unity.Hypercasual.asmdef index 5c68fe24..99a793c0 100644 --- a/Assets/Unity.Hypercasual.asmdef +++ b/Assets/Unity.Hypercasual.asmdef @@ -1,27 +1,28 @@ { - "name": "Unity.Hypercasual", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:6055be8ebefd69e48b49212b09b47b2f", - "GUID:ff6de30450f3748908ff580f6ec64d9a", - "GUID:78c2789dfc155bf4b9e815b0ca402b9b", - "GUID:b68f5bb197434c84c8a4cc3e45e8408b", - "GUID:9fc1342f87877ac42a37b19ac1c6653c", - "GUID:f51ebe6a0ceec4240a699833d6309b23", - "GUID:39350674e628e4d2aa1dbede8297dcb0", - "GUID:a0996310e1aa34b7fbf14df5d255461d", - "GUID:c7a369c5a572d4b6b84cab646212889e", - "GUID:95d173a3e67b39d40803000ed05b79f4", - "GUID:95a2b1ff23bee4357a10943aba1b014d" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false + "name": "Unity.Hypercasual", + "rootNamespace": "", + "references": [ + "GUID:75469ad4d38634e559750d17036d5f7c", + "GUID:6055be8ebefd69e48b49212b09b47b2f", + "GUID:ff6de30450f3748908ff580f6ec64d9a", + "GUID:78c2789dfc155bf4b9e815b0ca402b9b", + "GUID:b68f5bb197434c84c8a4cc3e45e8408b", + "GUID:9fc1342f87877ac42a37b19ac1c6653c", + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:39350674e628e4d2aa1dbede8297dcb0", + "GUID:a0996310e1aa34b7fbf14df5d255461d", + "GUID:c7a369c5a572d4b6b84cab646212889e", + "GUID:95d173a3e67b39d40803000ed05b79f4", + "GUID:95a2b1ff23bee4357a10943aba1b014d", + "GUID:1d9728650655047939a351b40befbcdb" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false } \ No newline at end of file diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 952860c3..7e6a2e70 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -23,7 +23,7 @@ "dependencies": { "com.cysharp.unitask": "2.3.3" }, - "hash": "79203ec6a000ded00b84360e4f7ecfdc58d9f42e" + "hash": "01fdea8065a855144ab98514d95f70e8d9a2f74e" }, "com.immutable.passport": { "version": "file:/Users/natalie/Development/unity-immutable-sdk/src/Packages/Passport",