Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 143 additions & 8 deletions Assets/SequenceSDK/Marketplace/CurrencySwapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ public async Task GetSwapPriceTest()
CurrencySwap currencySwap = new CurrencySwap(_chain);
string amount = "1000";

SwapPrice swapPrice = await currencySwap.GetSwapPrice(new Address(USDC), new Address(USDCe), amount);
SwapPrice swapPrice = await currencySwap.GetSwapPrice(new Address("0xe8db071f698aBA1d60babaE8e08F5cBc28782108"), new Address(USDC), new Address(USDCe), amount);

Assert.IsNotNull(swapPrice);
Assert.AreEqual(USDCe.ToLower(), swapPrice.currencyAddress.Value.ToLower());
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.price));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.maxPrice));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.transactionValue));
Assert.GreaterOrEqual(BigInteger.Parse(swapPrice.transactionValue), BigInteger.Zero);
}

[Test]
Expand All @@ -41,9 +38,7 @@ public async Task GetSwapPricesTest()
{
Assert.IsNotNull(swapPrice);
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.price));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.maxPrice));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapPrice.transactionValue));
Assert.GreaterOrEqual(BigInteger.Parse(swapPrice.transactionValue), BigInteger.Zero);
Assert.NotNull(swapPrice.currencyAddress);
}
}

Expand Down Expand Up @@ -81,6 +76,8 @@ public async Task GetSwapQuoteTest()
Assert.IsFalse(string.IsNullOrWhiteSpace(swapQuote.transactionValue));
Assert.GreaterOrEqual(BigInteger.Parse(swapQuote.transactionValue), BigInteger.Zero);
Assert.IsFalse(string.IsNullOrWhiteSpace(swapQuote.approveData));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapQuote.amount));
Assert.IsFalse(string.IsNullOrWhiteSpace(swapQuote.amountMin));
}

[Test]
Expand All @@ -98,7 +95,7 @@ public async Task GetSwapQuoteTest_InsufficientBalance()
}
catch (Exception e)
{
Assert.IsTrue(e.Message.Contains("Insufficient balance"));
Assert.IsTrue(e.Message.Contains("not enough balance for swap"));
}
}

Expand All @@ -120,5 +117,143 @@ public async Task GetSwapQuoteTest_FailedToFetchPrice()
Assert.IsTrue(e.Message.Contains("Error fetching swap quote"));
}
}

[Test]
public async Task TestGetSupportedChains()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);

try
{
Chain[] supportedChains = await currencySwap.GetSupportedChains();
Assert.IsNotNull(supportedChains);
Assert.Greater(supportedChains.Length, 0);
}
catch (Exception e)
{
Assert.Fail($"Exception encountered while fetching supported chains: {e.Message}");
}
}

[Test]
public async Task TestGetSupportedTokens()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);

try
{
Token[] supportedTokens = await currencySwap.GetSupportedTokens(new[] { _chain });
Assert.IsNotNull(supportedTokens);
Assert.Greater(supportedTokens.Length, 0);
}
catch (Exception e)
{
Assert.Fail($"Exception encountered while fetching supported tokens: {e.Message}");
}
}

[Test]
public async Task TestGetSupportedTokens_EmptyChains()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);

try
{
Token[] supportedTokens = await currencySwap.GetSupportedTokens(new Chain[0]);
Assert.Fail("Expected exception but none was thrown");
}
catch (Exception e)
{
Assert.IsTrue(e.Message.Contains("Error fetching supported tokens:"));
}
}

[Test]
public async Task TestGetSupportedTokens_NullChains()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);

try
{
Token[] supportedTokens = await currencySwap.GetSupportedTokens(null);
Assert.Fail("Expected exception but none was thrown");
}
catch (Exception e)
{
Assert.IsTrue(e.Message.Contains("Error fetching supported tokens:"));
}
}

[Test]
public async Task TestGetSupportedTokens_AllSupportedChains()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);

try
{
Chain[] supportedChains = await currencySwap.GetSupportedChains();
Assert.IsNotNull(supportedChains);
Assert.Greater(supportedChains.Length, 0);

Token[] supportedTokens = await currencySwap.GetSupportedTokens(supportedChains);
Assert.IsNotNull(supportedTokens);
Assert.Greater(supportedTokens.Length, 0);
}
catch (Exception e)
{
Assert.Fail($"Exception encountered while fetching supported tokens: {e.Message}");
}
}

[Test]
public async Task TestGetLifiSwapRoutes()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);
try
{
LifiSwapRoute[] swapRoutes = await currencySwap.GetLifiSwapRoutes(
new Address("0xe8db071f698aBA1d60babaE8e08F5cBc28782108"), new Address(USDC), "1000");
Assert.NotNull(swapRoutes);
Assert.Greater(swapRoutes.Length, 0);
}
catch (Exception e)
{
Assert.Fail($"Exception encountered while fetching Lifi swap routes: {e.Message}");
}
}

[Test]
public async Task TestGetLifiSwapQuote()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);
try
{
LifiSwapQuote swapQuote = await currencySwap.GetLifiSwapQuote(
new Address("0xe8db071f698aBA1d60babaE8e08F5cBc28782108"), new Address(USDC), new Address(USDCe),
"1000");
Assert.NotNull(swapQuote);
Assert.AreEqual(USDCe.ToLower(), swapQuote.currencyAddress.Value.ToLower());
}
catch (Exception e)
{
Assert.Fail($"Exception encountered while fetching Lifi swap quote: {e.Message}");
}
}

[Test]
public async Task TestGetLifiSwapQuote_NoAmounts()
{
CurrencySwap currencySwap = new CurrencySwap(_chain);
try
{
LifiSwapQuote swapQuote = await currencySwap.GetLifiSwapQuote(
new Address("0xe8db071f698aBA1d60babaE8e08F5cBc28782108"), new Address(USDC), new Address(USDCe));
Assert.Fail("Expected exception but none was thrown");
}
catch (Exception e)
{
Assert.IsTrue(e.Message.Contains("Error fetching Lifi swap quote:"));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public MockSwapThatGivesPricesInOrder(ulong[] maxPrices)
public event Action<SwapPrice> OnSwapPriceReturn;
public event Action<string> OnSwapPriceError;

public Task<SwapPrice> GetSwapPrice(Address userWallet, Address buyCurrency, Address sellCurrency, string buyAmount)
{
throw new NotImplementedException();
}

public async Task<SwapPrice> GetSwapPrice(Address buyCurrency, Address sellCurrency, string buyAmount,
uint slippagePercent = ISwap.DefaultSlippagePercentage)
{
Expand Down Expand Up @@ -48,5 +53,20 @@ public Task<SwapQuote> GetSwapQuote(Address userWallet, Address buyCurrency, Add
{
throw new NotImplementedException();
}

public Task<Chain[]> GetSupportedChains()
{
throw new NotImplementedException();
}

public Task<Token[]> GetSupportedTokens(Chain[] chains)
{
throw new NotImplementedException();
}

public Task<LifiSwapRoute[]> GetLifiSwapRoutes(Address userWallet, Address buyCurrency, string buyAmount)
{
throw new NotImplementedException();
}
}
}
167 changes: 167 additions & 0 deletions Packages/Sequence-Unity/Sequence/SequenceSDK/Ethereum/Token.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using System;
using System.Numerics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine.Scripting;

namespace Sequence
{
[Serializable]
[JsonConverter(typeof(TokenConverter))]
public class Token
{
public Chain Chain;
public Address Contract;
public string TokenId;
public string Symbol;
public string Name;
public BigInteger Decimals;
public BigInteger Price;
public decimal PriceUsd;
public string LogoUri;

public Token(Chain chain, Address contract, string tokenId = null, string symbol = null, string name = null,
BigInteger decimals = default, decimal priceUsd = default, string logoUri = null, BigInteger price = default)
{
Chain = chain;
Contract = contract;
TokenId = tokenId;
Symbol = symbol;
Name = name;
Decimals = decimals;
PriceUsd = priceUsd;
LogoUri = logoUri;
Price = price;
}

[Preserve]
[JsonConstructor]
public Token(BigInteger chainId, string contractAddress, string tokenId = null, string symbol = null,
string name = null, BigInteger decimals = default, decimal priceUsd = default, string logoUri = null, BigInteger price = default)
{
Chain = ChainDictionaries.ChainById[chainId.ToString()];
if (!string.IsNullOrWhiteSpace(contractAddress))
{
Contract = new Address(contractAddress);
}
TokenId = tokenId;
Symbol = symbol;
Name = name;
Decimals = decimals;
PriceUsd = priceUsd;
LogoUri = logoUri;
Price = price;
}
}

internal class TokenConverter : JsonConverter<Token>
{
public override void WriteJson(JsonWriter writer, Token value, JsonSerializer serializer)
{
var jsonObject = new JObject
{
["chainId"] = ulong.Parse(ChainDictionaries.ChainIdOf[value.Chain]),
["contractAddress"] = value.Contract.ToString(),
};
if (value.TokenId != null)
{
jsonObject["tokenId"] = value.TokenId;
}
if (value.Symbol != null)
{
jsonObject["symbol"] = value.Symbol;
}
if (value.Name != null)
{
jsonObject["name"] = value.Name;
}
if (value.Decimals != default)
{
jsonObject["decimals"] = value.Decimals.ToString();
}
if (value.PriceUsd != default)
{
jsonObject["priceUsd"] = value.PriceUsd;
}
if (value.LogoUri != null)
{
jsonObject["logoUri"] = value.LogoUri;
}
if (value.Price != default)
{
jsonObject["price"] = value.Price.ToString();
}

jsonObject.WriteTo(writer);
}

public override Token ReadJson(JsonReader reader, Type objectType, Token existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);

BigInteger chainId = jsonObject["chainId"]?.Value<ulong>() ?? 0;
string contractAddress = jsonObject["contractAddress"]?.Value<string>();
if (string.IsNullOrWhiteSpace(contractAddress))
{
contractAddress = jsonObject["address"]?.Value<string>();
}
string tokenId = jsonObject["tokenId"]?.Value<string>();
string symbol = jsonObject["symbol"]?.Value<string>();
string name = jsonObject["name"]?.Value<string>();
BigInteger decimals = (jsonObject["decimals"]?.Value<ulong>() ?? 18);
decimal priceUsd = jsonObject["priceUsd"]?.Value<decimal>() ?? default;
string logoUri = jsonObject["logoUri"]?.Value<string>();
BigInteger price = 0;
JToken priceToken = jsonObject["price"];
if (priceToken != null && priceToken.Type != JTokenType.Null)
{
string priceStr = priceToken.Value<string>();
if (!string.IsNullOrWhiteSpace(priceStr) && BigInteger.TryParse(priceStr, out var parsedPrice))
{
price = parsedPrice;
}
}


return new Token(chainId, contractAddress, tokenId, symbol, name, decimals, priceUsd, logoUri, price);
}
}

public static class TokenExtensions
{
public static bool ContainsToken(this Token[] tokens, Token token)
{
if (tokens == null || token == null)
{
return false;
}
foreach (var t in tokens)
{
if (t.Chain == token.Chain && t.Contract.Equals(token.Contract) && t.TokenId == token.TokenId)
{
return true;
}
}

return false;
}

public static bool ContainsToken(this Token[] tokens, Address token)
{
if (tokens == null || token == null)
{
return false;
}
foreach (var t in tokens)
{
if (t.Contract.Equals(token))
{
return true;
}
}

return false;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading