Skip to content

Commit

Permalink
Merge pull request #159 from IOTA-NET/158-feat-send-outputs
Browse files Browse the repository at this point in the history
158 feat send outputs
  • Loading branch information
wireless90 committed Jan 16, 2023
2 parents 14e6676 + 0b023eb commit 71c296f
Show file tree
Hide file tree
Showing 23 changed files with 227 additions and 22 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ For more examples, see the [Examples](https://github.com/wireless90/IotaWallet.N

### Commands

- [x] BuildBasicOutput
- [x] BurnNativeTokens
- [x] BurnNft
- [x] ClaimOutputs
Expand All @@ -171,6 +172,7 @@ For more examples, see the [Examples](https://github.com/wireless90/IotaWallet.N
- [x] SendMicroAmount
- [x] SendNativeTokens
- [x] SendNfts
- [x] SendOutputs
- [x] SyncAccount

### Queries
Expand Down
15 changes: 14 additions & 1 deletion csharp/IotaWalletNet/IotaWalletNet.Application/Account.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using IotaWalletNet.Application.AccountContext.Commands.BurnNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput;
using IotaWalletNet.Application.AccountContext.Commands.BurnNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.BurnNft;
using IotaWalletNet.Application.AccountContext.Commands.ClaimOutputs;
using IotaWalletNet.Application.AccountContext.Commands.ConsolidateOutputs;
Expand All @@ -14,6 +15,7 @@
using IotaWalletNet.Application.AccountContext.Commands.SendMicroAmount;
using IotaWalletNet.Application.AccountContext.Commands.SendNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.SendNfts;
using IotaWalletNet.Application.AccountContext.Commands.SendOutputs;
using IotaWalletNet.Application.AccountContext.Commands.SyncAccount;
using IotaWalletNet.Application.AccountContext.Queries.GetAddresses;
using IotaWalletNet.Application.AccountContext.Queries.GetAddressesWithUnspentOutputs;
Expand All @@ -34,6 +36,7 @@
using IotaWalletNet.Domain.Common.Models.Network;
using IotaWalletNet.Domain.Common.Models.Nft;
using IotaWalletNet.Domain.Common.Models.Output;
using IotaWalletNet.Domain.Common.Models.Output.OutputDataTypes;
using IotaWalletNet.Domain.Common.Models.Transaction.PayloadTypes;
using IotaWalletNet.Domain.PlatformInvoke;
using MediatR;
Expand All @@ -56,6 +59,16 @@ public Account(IMediator mediator, string username, IWallet wallet)
public IWallet Wallet { get; }


public async Task<SendOutputsResponse> SendOutputsAsync(List<IOutputType> outputs, TaggedDataPayload? taggedDataPayload = null)
{
return await _mediator.Send(new SendOutputsCommand(this, Username, outputs, taggedDataPayload));
}

public async Task<BuildBasicOutputResponse> BuildBasicOutputAsync(BuildBasicOutputData buildBasicOutputData)
{
return await _mediator.Send(new BuildBasicOutputCommand(buildBasicOutputData, Username, this));
}

public async Task<Task> EnablePeriodicSyncing(int intervalInMilliSeconds)
{
return await _mediator.Send(new EnablePeriodicSyncingCommand(this, intervalInMilliSeconds));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using IotaWalletNet.Application.Common.Interfaces;
using IotaWalletNet.Domain.Common.Models.Output.OutputDataTypes;
using MediatR;

namespace IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput
{
public class BuildBasicOutputCommand : IRequest<BuildBasicOutputResponse>
{
public BuildBasicOutputCommand(BuildBasicOutputData data, string username, IAccount account)
{
Data = data;
Username = username;
Account = account;
}

public BuildBasicOutputData Data { get; set; }

public string Username { get; set; }

public IAccount Account { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using IotaWalletNet.Domain.PlatformInvoke;
using MediatR;
using Newtonsoft.Json;

namespace IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput
{
public class BuildBasicOutputCommandHandler : IRequestHandler<BuildBasicOutputCommand, BuildBasicOutputResponse>
{
public async Task<BuildBasicOutputResponse> Handle(BuildBasicOutputCommand request, CancellationToken cancellationToken)
{
BuildBasicOutputCommandMessage message = new BuildBasicOutputCommandMessage(request.Username, request.Data);
string jsonMessage = JsonConvert.SerializeObject(message);

RustBridgeGenericResponse rustBridgeGenericResponse = await request.Account.SendMessageAsync(jsonMessage);

BuildBasicOutputResponse buildBasicOutputResponse = rustBridgeGenericResponse.As<BuildBasicOutputResponse>()!;

return buildBasicOutputResponse;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using IotaWalletNet.Domain.Common.Models;
using IotaWalletNet.Domain.Common.Models.Output.OutputDataTypes;

namespace IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput
{
public class BuildBasicOutputCommandMessage : AccountMessage<BuildBasicOutputData>
{
private const string METHOD_NAME = "buildBasicOutput";
public BuildBasicOutputCommandMessage(string username, BuildBasicOutputData? methodData)
: base(username, METHOD_NAME, methodData)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using IotaWalletNet.Domain.Common.Models.Output.OutputTypes;
using IotaWalletNet.Domain.PlatformInvoke;

namespace IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput
{
public class BuildBasicOutputResponse : RustBridgeResponseBase<BasicOutput>
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public EnablePeriodicSyncingCommand(IAccount account, int intervalInMilliSeconds

public IAccount Account { get; set; }

public int IntervalInMilliSeconds { get;set; }
public int IntervalInMilliSeconds { get; set; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace IotaWalletNet.Application.AccountContext.Commands.SendAmount
{
public class SendAmountCommand : IRequest<SendAmountResponse>
{
public SendAmountCommand(IAccount account, string username, List<AddressWithAmount> addressesWithAmount, TaggedDataPayload? taggedDataPayload)
public SendAmountCommand(IAccount account, string username, List<AddressWithAmount> addressesWithAmount, TaggedDataPayload? taggedDataPayload = null)
{
Account = account;
Username = username;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using IotaWalletNet.Application.Common.Interfaces;
using IotaWalletNet.Domain.Common.Interfaces;
using IotaWalletNet.Domain.Common.Models.Transaction.PayloadTypes;
using MediatR;

namespace IotaWalletNet.Application.AccountContext.Commands.SendOutputs
{
public class SendOutputsCommand : IRequest<SendOutputsResponse>
{
public SendOutputsCommand(IAccount account, string username, List<IOutputType> outputs, TaggedDataPayload? taggedDataPayload = null)
{
Account = account;
Username = username;
Outputs = outputs;
TaggedDataPayload = taggedDataPayload;
}

public IAccount Account { get; set; }

public string Username { get; set; }

public List<IOutputType> Outputs { get; set; }

public TaggedDataPayload? TaggedDataPayload { get; set; }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using IotaWalletNet.Domain.Common.Models.Transaction;
using IotaWalletNet.Domain.PlatformInvoke;
using MediatR;
using Newtonsoft.Json;

namespace IotaWalletNet.Application.AccountContext.Commands.SendOutputs
{
public class SendOutputsCommandHandler : IRequestHandler<SendOutputsCommand, SendOutputsResponse>
{
public async Task<SendOutputsResponse> Handle(SendOutputsCommand request, CancellationToken cancellationToken)
{
TransactionOptions transactionOptions = new TransactionOptions() { TaggedDataPayload = request.TaggedDataPayload };

SendOutputsCommandMessageData messageData = new SendOutputsCommandMessageData(request.Outputs, transactionOptions);

SendOutputsCommandMessage message = new SendOutputsCommandMessage(request.Username, messageData);

string messageJson = JsonConvert.SerializeObject(message);

RustBridgeGenericResponse rustBridgeGenericResponse = await request.Account.SendMessageAsync(messageJson);

SendOutputsResponse sendOutputsResponse = rustBridgeGenericResponse.As<SendOutputsResponse>()!;

return sendOutputsResponse;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using IotaWalletNet.Domain.Common.Models;

namespace IotaWalletNet.Application.AccountContext.Commands.SendOutputs
{
public class SendOutputsCommandMessage : AccountMessage<SendOutputsCommandMessageData>
{
private const string METHOD_NAME = "sendOutputs";
public SendOutputsCommandMessage(string username, SendOutputsCommandMessageData? methodData)
: base(username, METHOD_NAME, methodData)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using IotaWalletNet.Domain.Common.Interfaces;
using IotaWalletNet.Domain.Common.Models.Transaction;

namespace IotaWalletNet.Application.AccountContext.Commands.SendOutputs
{
public class SendOutputsCommandMessageData
{
public SendOutputsCommandMessageData(List<IOutputType> outputs, TransactionOptions options)
{
Outputs = outputs;
Options = options;
}

public List<IOutputType> Outputs { get; set; }

public TransactionOptions Options { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using IotaWalletNet.Domain.Common.Models.Transaction;
using IotaWalletNet.Domain.PlatformInvoke;

namespace IotaWalletNet.Application.AccountContext.Commands.SendOutputs
{
//Response
public class SendOutputsResponse : RustBridgeResponseBase<Transaction>
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class GetOutputsWithAdditionalUnlockConditionsMessage : AccountMessage<Ge
{
private const string METHOD_NAME = "getOutputsWithAdditionalUnlockConditions";

public GetOutputsWithAdditionalUnlockConditionsMessage(string username, GetOutputsWithAdditionalUnlockConditionsMessageData? methodData)
public GetOutputsWithAdditionalUnlockConditionsMessage(string username, GetOutputsWithAdditionalUnlockConditionsMessageData? methodData)
: base(username, METHOD_NAME, methodData)
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using IotaWalletNet.Application.AccountContext.Commands.BurnNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.BuildBasicOutput;
using IotaWalletNet.Application.AccountContext.Commands.BurnNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.BurnNft;
using IotaWalletNet.Application.AccountContext.Commands.ClaimOutputs;
using IotaWalletNet.Application.AccountContext.Commands.ConsolidateOutputs;
Expand All @@ -12,6 +13,7 @@
using IotaWalletNet.Application.AccountContext.Commands.SendMicroAmount;
using IotaWalletNet.Application.AccountContext.Commands.SendNativeTokens;
using IotaWalletNet.Application.AccountContext.Commands.SendNfts;
using IotaWalletNet.Application.AccountContext.Commands.SendOutputs;
using IotaWalletNet.Application.AccountContext.Commands.SyncAccount;
using IotaWalletNet.Application.AccountContext.Queries.GetAddresses;
using IotaWalletNet.Application.AccountContext.Queries.GetAddressesWithUnspentOutputs;
Expand All @@ -31,6 +33,7 @@
using IotaWalletNet.Domain.Common.Models.Network;
using IotaWalletNet.Domain.Common.Models.Nft;
using IotaWalletNet.Domain.Common.Models.Output;
using IotaWalletNet.Domain.Common.Models.Output.OutputDataTypes;
using IotaWalletNet.Domain.Common.Models.Transaction.PayloadTypes;

namespace IotaWalletNet.Application.Common.Interfaces
Expand Down Expand Up @@ -72,5 +75,7 @@ public interface IAccount : IRustBridgeCommunicator
SendMicroAmountBuilder SendMicroAmountUsingBuilder();
Task<GetOutputsWithAdditionalUnlockConditionsResponse> GetOutputsWithAdditionalUnlockConditionsAsync(OutputTypeToClaim outputTypeToClaim);
Task<Task> EnablePeriodicSyncing(int intervalInMilliSeconds);
Task<BuildBasicOutputResponse> BuildBasicOutputAsync(BuildBasicOutputData buildBasicOutputData);
Task<SendOutputsResponse> SendOutputsAsync(List<IOutputType> outputs, TaggedDataPayload? taggedDataPayload = null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private static string PreprocessHexEncodedAmountString(string hexEncodedAmount)
if (hexEncodedAmount.ToLower().StartsWith("0x"))
hexEncodedAmount = hexEncodedAmount.Substring(2);

if(hexEncodedAmount.Length % 2 != 0)
if (hexEncodedAmount.Length % 2 != 0)
hexEncodedAmount = "0" + hexEncodedAmount;

return hexEncodedAmount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using IotaWalletNet.Domain.Common.Models.Address;
using IotaWalletNet.Domain.Common.Models.Coin;
using IotaWalletNet.Domain.Common.Models.Network;
using System.Buffers.Text;
using System.Text;

namespace IotaWalletNet.Domain.Common.Extensions
Expand All @@ -14,13 +13,13 @@ public static class StringExtensions

public static bool IsNotNullAndEmpty(this string? input) => !input.IsNullOrEmpty();

public static string ToHexString(this string input)
public static string ToHexString(this string input)
=> "0x" + Convert.ToHexString(Encoding.UTF8.GetBytes(input));


public static string FromHexString(this string hexString)
{
if(hexString.ToLower().StartsWith("0x"))
if (hexString.ToLower().StartsWith("0x"))
hexString = hexString.Substring(2); // remove the 0x of a hexstring eg 0x1337

// eg 0x0 becomes 0 then becomes 00, to be able to use fromhexstring, we need length of hexstring to be % 2
Expand All @@ -47,7 +46,7 @@ public static string ComputeBlake2bHash(this string hexEncoded)

return "0x" + Convert.ToHexString(hash);
}

public static string EncodeEd25519HashIntoBech32(this string blake2bHashOfEd25519, NetworkType networkType, TypeOfCoin typeOfCoin)
{
blake2bHashOfEd25519 = blake2bHashOfEd25519.Trim().ToLower();
Expand All @@ -74,7 +73,7 @@ public static string DecodeBech32IntoEd25519Hash(this string bech32, NetworkType
string bech32OfInterest = bech32.Substring(4); //eg remove iota1 or smr1 or atoi1 or rms1

byte[] decoded = Bech32Engine.Decode(bech32OfInterest, hrp);

return "0x" + Convert.ToHexString(decoded);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using IotaWalletNet.Domain.Common.Interfaces;
using IotaWalletNet.Domain.Common.Models.Coin;

namespace IotaWalletNet.Domain.Common.Models.Output.OutputDataTypes
{
public class BuildBasicOutputData
{
public BuildBasicOutputData(string? amount, NativeToken? nativeTokens, List<IUnlockConditionType> unlockConditions, List<IFeatureType>? features)
{
Amount = amount;
NativeTokens = nativeTokens;
UnlockConditions = unlockConditions;
Features = features;
}

/// <summary>
/// If not provided, minimum storage deposit will be used
/// </summary>
public string? Amount { get; set; }

public NativeToken? NativeTokens { get; set; }

public List<IUnlockConditionType> UnlockConditions { get; set; }

public List<IFeatureType>? Features { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static byte EnableLogging(string filename, string filterLevel)
Type[] paramTypes = { typeof(string), typeof(string) };
Object[] args = { filename, filterLevel };

return (byte)DynamicPInvokeBuilder(typeof(byte), ResolveLibraryNameFromPlatformType(), "iota_init_logger", args, paramTypes);
return (byte)DynamicPInvokeBuilder(typeof(byte), ResolveLibraryNameFromPlatformType(), "iota_init_logger", args, paramTypes);
}

public static void CloseIotaWallet(IntPtr walletHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static async Task Run()


nativeTokenBalance = getBalanceResponse.Payload?.NativeTokens?.First(nativeTokenBalance => nativeTokenBalance.TokenId == tokenId)!;


Console.WriteLine($"After burning, we now have {nativeTokenBalance.Total.FromHexEncodedAmountToUInt64()} tokens left.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static async Task Run()


string amount = 10.ToHexEncodedAmount();

MeltNativeTokensResponse meltNativeTokensResponse = await account.MeltNativeTokensAsync(tokenId, amount);

Thread.Sleep(12000);
Expand Down
Loading

0 comments on commit 71c296f

Please sign in to comment.