diff --git a/src/Mx.NET.SDK.Core/Domain/Abi/AbiDefinition.cs b/src/Mx.NET.SDK.Core/Domain/Abi/AbiDefinition.cs index d63ae48..579df26 100644 --- a/src/Mx.NET.SDK.Core/Domain/Abi/AbiDefinition.cs +++ b/src/Mx.NET.SDK.Core/Domain/Abi/AbiDefinition.cs @@ -40,72 +40,28 @@ public EventDefinition GetEventDefinition(string identifier) return new EventDefinition(identifier, inputs.ToArray()); } - private TypeValue GetTypeValue(string rustType) + private TypeValue GetTypeValue(string type) { - var optional = new Regex("^optional<(.*)>$"); - var option = new Regex("^Option<(.*)>$"); - var multi = new Regex("^multi<(.*)>$"); - var tuple = new Regex("^tuple<(.*)>$"); - var variadic = new Regex("^variadic<(.*)>$"); - var list = new Regex("^List<(.*)>$"); - var array = new Regex("^Array<(.*)>$"); - - if (optional.IsMatch(rustType)) - { - var innerType = optional.Match(rustType).Groups[1].Value; - var innerTypeValue = GetTypeValue(innerType); - return TypeValue.OptionalValue(innerTypeValue); - } - - if (option.IsMatch(rustType)) - { - var innerType = option.Match(rustType).Groups[1].Value; - var innerTypeValue = GetTypeValue(innerType); - return TypeValue.OptionValue(innerTypeValue); - } - - if (multi.IsMatch(rustType)) + var pattern = new Regex("^(.*?)<(.*)>$"); + if (pattern.IsMatch(type)) { - var innerTypes = multi.Match(rustType).Groups[1].Value.Split(',').Where(s => !string.IsNullOrEmpty(s)); - var innerTypeValues = innerTypes.Select(GetTypeValue).ToArray(); - return TypeValue.MultiValue(innerTypeValues); - } + var parentType = pattern.Match(type).Groups[1].Value; + var innerType = pattern.Match(type).Groups[2].Value; - if (tuple.IsMatch(rustType)) - { - var innerTypes = tuple.Match(rustType).Groups[1].Value.Split(',').Where(s => !string.IsNullOrEmpty(s)); + var innerTypes = pattern.IsMatch(innerType) ? new[] { innerType } : innerType.Split(',').Where(s => !string.IsNullOrEmpty(s)); var innerTypeValues = innerTypes.Select(GetTypeValue).ToArray(); - return TypeValue.TupleValue(innerTypeValues); - } - - if (variadic.IsMatch(rustType)) - { - var innerType = variadic.Match(rustType).Groups[1].Value; - var innerTypeValue = GetTypeValue(innerType); - return TypeValue.VariadicValue(innerTypeValue); - } - - if (list.IsMatch(rustType)) - { - var innerType = list.Match(rustType).Groups[1].Value; - var innerTypeValue = GetTypeValue(innerType); - return TypeValue.ListValue(innerTypeValue); - } - - if (array.IsMatch(rustType)) - { - var innerType = array.Match(rustType).Groups[1].Value; - var innerTypeValue = GetTypeValue(innerType); - return TypeValue.ArrayValue(innerTypeValue); + var typeFromLearnedTypes = TypeValue.FromLearnedType(parentType, innerTypeValues); + if (typeFromLearnedTypes != null) + return typeFromLearnedTypes; } - var typeFromBaseRustType = TypeValue.FromRustType(rustType); + var typeFromBaseRustType = TypeValue.FromRustType(type); if (typeFromBaseRustType != null) return typeFromBaseRustType; - if (Types.Keys.Contains(rustType)) + if (Types.Keys.Contains(type)) { - var typeFromStruct = Types[rustType]; + var typeFromStruct = Types[type]; if (typeFromStruct.Type == "enum") { return TypeValue.EnumValue(typeFromStruct.Type, diff --git a/src/Mx.NET.SDK.Core/Domain/Codec/ArrayBinaryCodec.cs b/src/Mx.NET.SDK.Core/Domain/Codec/ArrayBinaryCodec.cs index cb7e614..0467c41 100644 --- a/src/Mx.NET.SDK.Core/Domain/Codec/ArrayBinaryCodec.cs +++ b/src/Mx.NET.SDK.Core/Domain/Codec/ArrayBinaryCodec.cs @@ -1,64 +1,63 @@ using System.Collections.Generic; using System.Linq; -using Mx.NET.SDK.Core.Domain.Exceptions; using Mx.NET.SDK.Core.Domain.Helper; using Mx.NET.SDK.Core.Domain.Values; namespace Mx.NET.SDK.Core.Domain.Codec { public class ArrayBinaryCodec : IBinaryCodec - { - private readonly BinaryCodec _binaryCodec; - - public ArrayBinaryCodec(BinaryCodec binaryCodec) - { - _binaryCodec = binaryCodec; - } - - public string Type => TypeValue.BinaryTypes.Array; - - public (IBinaryType Value, int BytesLength) DecodeNested(byte[] data, TypeValue type) - { - var result = new List(); - var originalBuffer = data; - var offset = 0; - - while (data.Length > 0) - { - var (value, bytesLength) = _binaryCodec.DecodeNested(data, type.InnerType); - result.Add(value); - offset += bytesLength; - data = originalBuffer.Slice(offset); - } - - var arrayValue = new ArrayValue(type, type.InnerType, result.ToArray()); - return (arrayValue, offset); - } - - public IBinaryType DecodeTopLevel(byte[] data, TypeValue type) - { - var (value, _) = DecodeNested(data, type); - return value; - } - - public byte[] EncodeNested(IBinaryType value) - { - var arrayValueObject = value.ValueOf(); - var buffers = new List(); - - foreach (var arrayValue in arrayValueObject.Values) - { - var fieldBuffer = _binaryCodec.EncodeNested(arrayValue); - buffers.Add(fieldBuffer); - } - - var data = buffers.SelectMany(s => s); - return data.ToArray(); - } - - public byte[] EncodeTopLevel(IBinaryType value) - { - return EncodeNested(value); - } - } + { + private readonly BinaryCodec _binaryCodec; + + public ArrayBinaryCodec(BinaryCodec binaryCodec) + { + _binaryCodec = binaryCodec; + } + + public string Type => TypeValue.BinaryTypes.Array; + + public (IBinaryType Value, int BytesLength) DecodeNested(byte[] data, TypeValue type) + { + var result = new List(); + var originalBuffer = data; + var offset = 0; + + for (int i = 0; i < type.Length; i++) + { + var (value, bytesLength) = _binaryCodec.DecodeNested(data, type.InnerType); + result.Add(value); + offset += bytesLength; + data = originalBuffer.Slice(offset); + } + + var arrayValue = new ArrayValue(type, type.InnerType, result.ToArray()); + return (arrayValue, offset); + } + + public IBinaryType DecodeTopLevel(byte[] data, TypeValue type) + { + var (value, _) = DecodeNested(data, type); + return value; + } + + public byte[] EncodeNested(IBinaryType value) + { + var arrayValueObject = value.ValueOf(); + var buffers = new List(); + + foreach (var arrayValue in arrayValueObject.Values) + { + var fieldBuffer = _binaryCodec.EncodeNested(arrayValue); + buffers.Add(fieldBuffer); + } + + var data = buffers.SelectMany(s => s); + return data.ToArray(); + } + + public byte[] EncodeTopLevel(IBinaryType value) + { + return EncodeNested(value); + } + } } diff --git a/src/Mx.NET.SDK.Core/Domain/Values/ArrayValue.cs b/src/Mx.NET.SDK.Core/Domain/Values/ArrayValue.cs index 836f361..93536d2 100644 --- a/src/Mx.NET.SDK.Core/Domain/Values/ArrayValue.cs +++ b/src/Mx.NET.SDK.Core/Domain/Values/ArrayValue.cs @@ -1,5 +1,4 @@ using Mx.NET.SDK.Core.Domain.Helper; -using System.Collections.Generic; using System.Linq; using System.Text; @@ -18,7 +17,7 @@ public ArrayValue(TypeValue type, TypeValue innerType, IBinaryType[] values) : b public static ArrayValue From(TypeValue type, params IBinaryType[] values) { - return new ArrayValue(TypeValue.ArrayValue(type), type.InnerType, values); + return new ArrayValue(TypeValue.ArrayValue(type, values.Length), type.InnerType, values); } public override string ToString() diff --git a/src/Mx.NET.SDK.Core/Domain/Values/TypeValue.cs b/src/Mx.NET.SDK.Core/Domain/Values/TypeValue.cs index cc0d263..d498e43 100644 --- a/src/Mx.NET.SDK.Core/Domain/Values/TypeValue.cs +++ b/src/Mx.NET.SDK.Core/Domain/Values/TypeValue.cs @@ -10,6 +10,7 @@ public class TypeValue public string RustType { get; } public TypeValue InnerType { get; } public TypeValue[] MultiTypes { get; } + public int? Length { get; } private readonly int? _sizeInBytes; private readonly bool? _withSign; @@ -31,10 +32,11 @@ public TypeValue(string binaryType, string rustType, FieldDefinition[] fieldDefi _fieldDefinitions = fieldDefinitions; } - public TypeValue(string binaryType, TypeValue innerType = null) + public TypeValue(string binaryType, TypeValue innerType = null, int? length = null) { BinaryType = binaryType; InnerType = innerType; + Length = length; } public TypeValue(string binaryType, TypeValue[] multiTypes) @@ -83,6 +85,39 @@ public static class BinaryTypes public const string Enum = nameof(Enum); } + public static class LearnedTypes + { + public const string Option = "Option"; + public const string List = "List"; + public const string VarArgs = "VarArgs"; + public const string MultiResultVec = "MultiResultVec"; + public const string Variadic = "variadic"; + public const string OptionalArg = "OptionalArg"; + public const string Optional = "optional"; + public const string OptionalResult = "OptionalResult"; + public const string Multi = "multi"; + public const string MultiArg = "MultiArg"; + public const string MultiResult = "MultiResult"; + public const string Tuple = "tuple"; + public const string Tuple2 = "tuple2"; + public const string Tuple3 = "tuple3"; + public const string Tuple4 = "tuple4"; + public const string Tuple5 = "tuple5"; + public const string Tuple6 = "tuple6"; + public const string Tuple7 = "tuple7"; + public const string Tuple8 = "tuple8"; + public const string Array = "Array"; + public const string Array2 = "array2"; + public const string Array8 = "array8"; + public const string Array16 = "array16"; + public const string Array20 = "array20"; + public const string Array32 = "array32"; + public const string Array46 = "array46"; + public const string Array64 = "array64"; + public const string Array128 = "array128"; + public const string Array256 = "array256"; + } + public static class RustTypes { public const string U8 = "u8"; @@ -136,13 +171,72 @@ public static class RustTypes public static TypeValue TupleValue(TypeValue[] tupleTypes) => new TypeValue(BinaryTypes.Tuple, tupleTypes); public static TypeValue VariadicValue(TypeValue innerType) => new TypeValue(BinaryTypes.Variadic, innerType); public static TypeValue ListValue(TypeValue innerType) => new TypeValue(BinaryTypes.List, innerType); - public static TypeValue ArrayValue(TypeValue innerType) => new TypeValue(BinaryTypes.Array, innerType); - + public static TypeValue ArrayValue(TypeValue innerType, int length) => new TypeValue(BinaryTypes.Array, innerType, length); + public static TypeValue StructValue(string name, FieldDefinition[] fieldDefinitions) => new TypeValue(BinaryTypes.Struct, name, fieldDefinitions); public static TypeValue EnumValue(string name, FieldDefinition[] fieldDefinitions) => new TypeValue(BinaryTypes.Enum, name, fieldDefinitions); + public static TypeValue FromLearnedType(string learnedType, TypeValue[] types) + { + switch (learnedType) + { + case LearnedTypes.Option: + return OptionValue(types[0]); + + case LearnedTypes.List: + return ListValue(types[0]); + + case LearnedTypes.VarArgs: + case LearnedTypes.MultiResultVec: + case LearnedTypes.Variadic: + return VariadicValue(types[0]); + + case LearnedTypes.OptionalArg: + case LearnedTypes.Optional: + case LearnedTypes.OptionalResult: + return OptionalValue(types[0]); + + case LearnedTypes.Multi: + case LearnedTypes.MultiArg: + case LearnedTypes.MultiResult: + return MultiValue(types); + + case LearnedTypes.Tuple: + case LearnedTypes.Tuple2: + case LearnedTypes.Tuple3: + case LearnedTypes.Tuple4: + case LearnedTypes.Tuple5: + case LearnedTypes.Tuple6: + case LearnedTypes.Tuple7: + case LearnedTypes.Tuple8: + return TupleValue(types); + + case LearnedTypes.Array2: + return ArrayValue(types[0], 2); + case LearnedTypes.Array8: + return ArrayValue(types[0], 8); + case LearnedTypes.Array16: + return ArrayValue(types[0], 16); + case LearnedTypes.Array20: + return ArrayValue(types[0], 20); + case LearnedTypes.Array32: + return ArrayValue(types[0], 32); + case LearnedTypes.Array46: + return ArrayValue(types[0], 46); + case LearnedTypes.Array64: + return ArrayValue(types[0], 64); + case LearnedTypes.Array128: + return ArrayValue(types[0], 128); + case LearnedTypes.Array256: + return ArrayValue(types[0], 256); + + default: + return null; + } + } + public static TypeValue FromRustType(string rustType) { switch (rustType) @@ -169,10 +263,10 @@ public static TypeValue FromRustType(string rustType) case RustTypes.Bigint: return BigIntTypeValue; - case RustTypes.Bytes: - return BytesValue; case RustTypes.Bool: return BooleanValue; + case RustTypes.Bytes: + return BytesValue; case RustTypes.Address: return AddressValue; case RustTypes.TokenIdentifier: diff --git a/src/Mx.NET.SDK.Core/Mx.NET.SDK.Core.csproj b/src/Mx.NET.SDK.Core/Mx.NET.SDK.Core.csproj index 9e50a6e..afcd390 100644 --- a/src/Mx.NET.SDK.Core/Mx.NET.SDK.Core.csproj +++ b/src/Mx.NET.SDK.Core/Mx.NET.SDK.Core.csproj @@ -11,7 +11,7 @@ https://github.com/RemarkableTools/Mx.NET.SDK/tree/main/src/Mx.NET.SDK.Core GitHub Remarkable Tools - 2.0.1 + 2.0.2 true RemarkableTools.Mx.Core README.md diff --git a/src/Mx.NET.SDK.Wallet/Mx.NET.SDK.Wallet.csproj b/src/Mx.NET.SDK.Wallet/Mx.NET.SDK.Wallet.csproj index e0b1ee7..1469665 100644 --- a/src/Mx.NET.SDK.Wallet/Mx.NET.SDK.Wallet.csproj +++ b/src/Mx.NET.SDK.Wallet/Mx.NET.SDK.Wallet.csproj @@ -11,7 +11,7 @@ https://github.com/RemarkableTools/Mx.NET.SDK/tree/main/src/Mx.NET.SDK.Wallet GitHub Remarkable Tools - 2.0.0 + 2.0.1 true LICENSE.txt RemarkableTools.Mx.Wallet diff --git a/src/Mx.NET.SDK.Wallet/Wallet/Mnemonic.cs b/src/Mx.NET.SDK.Wallet/Wallet/Mnemonic.cs index 193d6b4..40a25d7 100644 --- a/src/Mx.NET.SDK.Wallet/Wallet/Mnemonic.cs +++ b/src/Mx.NET.SDK.Wallet/Wallet/Mnemonic.cs @@ -25,6 +25,18 @@ public static Mnemonic Generate() return new Mnemonic(bip39.GenerateMnemonic(MNEMONIC_STRENGTH, BIP39Wordlist.English)); } + public static Mnemonic GenerateInShard(int expectedShard) + { + GENERATE: + var mnemonic = Generate(); + var publicKey = Wallet.FromMnemonic(mnemonic.SeedPhrase).GetPublicKey(); + var walletShard = new WalletPublicKey(publicKey).GetShard(); + if (walletShard != expectedShard) + goto GENERATE; + + return mnemonic; + } + public static Mnemonic FromString(string seedPhrase) { seedPhrase = seedPhrase.Trim(); diff --git a/src/Mx.NET.SDK.Wallet/Wallet/WalletKeys.cs b/src/Mx.NET.SDK.Wallet/Wallet/WalletKeys.cs index e46e201..8c46ca2 100644 --- a/src/Mx.NET.SDK.Wallet/Wallet/WalletKeys.cs +++ b/src/Mx.NET.SDK.Wallet/Wallet/WalletKeys.cs @@ -2,6 +2,7 @@ using Mx.NET.SDK.Core.Domain.Values; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Signers; +using System; namespace Mx.NET.SDK.Wallet.Wallet { @@ -101,6 +102,31 @@ public Address ToAddress() return Address.FromBytes(_publicKey); } + public int GetShard() + { + int startingIndex = _publicKey.Length - 1; + byte[] usedBuffer = new byte[_publicKey.Length - startingIndex]; + Array.Copy(_publicKey, startingIndex, usedBuffer, 0, usedBuffer.Length); + + int addr = 0; + for (int i = 0; i < usedBuffer.Length; i++) + { + addr = (addr << 8) + usedBuffer[i]; + } + + int n = (int)Math.Ceiling(Math.Log(3, 2)); + int maskHigh = (1 << n) - 1; + int maskLow = (1 << (n - 1)) - 1; + + int shard = addr & maskHigh; + if (shard > 2) + { + shard = addr & maskLow; + } + + return shard; + } + public bool Verify(byte[] data, byte[] signature) { var parameters = new Ed25519PublicKeyParameters(_publicKey, 0); diff --git a/src/Mx.NET.SDK/Domain/Data/Network/NetworkEconomicsMvx.cs b/src/Mx.NET.SDK/Domain/Data/Network/NetworkEconomicsMvx.cs index be73044..ce63998 100644 --- a/src/Mx.NET.SDK/Domain/Data/Network/NetworkEconomicsMvx.cs +++ b/src/Mx.NET.SDK/Domain/Data/Network/NetworkEconomicsMvx.cs @@ -1,5 +1,6 @@ using Mx.NET.SDK.Provider.API; using Mx.NET.SDK.Provider.Dtos.API.Network; +using System.Numerics; using System.Threading.Tasks; namespace Mx.NET.SDK.Domain.Data.Network @@ -14,7 +15,7 @@ public class NetworkEconomicsMvx public double Apr { get; set; } public double TotalUpApr { get; set; } public double BaseApr { get; set; } - public long TokenMarketCap { get; set; } + public BigInteger TokenMarketCap { get; set; } private NetworkEconomicsMvx(NetworkEconomicsDto economics) { diff --git a/src/Mx.NET.SDK/Mx.NET.SDK.csproj b/src/Mx.NET.SDK/Mx.NET.SDK.csproj index 80d7a1c..a179b4e 100644 --- a/src/Mx.NET.SDK/Mx.NET.SDK.csproj +++ b/src/Mx.NET.SDK/Mx.NET.SDK.csproj @@ -11,7 +11,7 @@ https://github.com/RemarkableTools/Mx.NET.SDK GitHub Remarkable Tools - 2.0.3 + 2.0.4 true RemarkableTools.Mx README.md diff --git a/src/Mx.NET.SDK/Provider/Dtos/API/Network/NetworkEconomicsDto.cs b/src/Mx.NET.SDK/Provider/Dtos/API/Network/NetworkEconomicsDto.cs index 471b589..e83b4af 100644 --- a/src/Mx.NET.SDK/Provider/Dtos/API/Network/NetworkEconomicsDto.cs +++ b/src/Mx.NET.SDK/Provider/Dtos/API/Network/NetworkEconomicsDto.cs @@ -1,4 +1,6 @@ -namespace Mx.NET.SDK.Provider.Dtos.API.Network +using System.Numerics; + +namespace Mx.NET.SDK.Provider.Dtos.API.Network { public class NetworkEconomicsDto { @@ -10,6 +12,6 @@ public class NetworkEconomicsDto public double Apr { get; set; } public double TotalUpApr { get; set; } public double BaseApr { get; set; } - public long TokenMarketCap { get; set; } + public BigInteger TokenMarketCap { get; set; } } } diff --git a/tests/MS Testing/MS Testing.csproj b/tests/MS Testing/MS Testing.csproj index 5a3ae02..b13d365 100644 --- a/tests/MS Testing/MS Testing.csproj +++ b/tests/MS Testing/MS Testing.csproj @@ -9,11 +9,9 @@ - - - - - + + +