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
23 changes: 16 additions & 7 deletions csharp/src/Workflow.Solana/Helpers/EventDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Train.Solver.Infrastructure.Abstractions.Models;
using Train.Solver.Workflow.Abstractions.Models;
using Train.Solver.Workflow.Solana.Programs.HTLCProgram;
using Train.Solver.Workflow.Solana.Programs.HtlcSolProgram;

namespace Train.Solver.Blockchain.Solana.Helpers;

Expand All @@ -34,9 +35,11 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(
{
var htlcTokenContractAddress = network.HTLCTokenContractAddress;

var htlcNativeContractAddress = network.HTLCNativeContractAddress;

var trackedBlockEvents = blockResponseResult.Result.Transactions
.Where(transaction => transaction.Transaction.Message.Instructions
.Any(instruction => instruction.ProgramId == htlcTokenContractAddress))
.Any(instruction => instruction.ProgramId == htlcTokenContractAddress || instruction.ProgramId == htlcNativeContractAddress))
.ToList();

foreach (var transaction in trackedBlockEvents)
Expand All @@ -47,11 +50,15 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(
var isLockEvent = transaction.Meta.LogMessages
.Any(x => x.Contains(SolanaConstants.HtlcConstants.addLockEventPrefixPattern));

var contractAddress = transaction.Transaction.Message.Instructions.Any(x => x.ProgramId == htlcTokenContractAddress) ?
htlcTokenContractAddress :
htlcNativeContractAddress;

var accountForSimulation = solverAccounts.First();

if (isCommitEvent)
{
var prefixPattern = "Program return: " + htlcTokenContractAddress + " ";
var prefixPattern = "Program return: " + contractAddress + " ";

var logResult = transaction.Meta.LogMessages.Where(s => s.StartsWith(prefixPattern))
.Select(s => s.Substring(prefixPattern.Length))
Expand All @@ -63,6 +70,7 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(
var commitEvent = await DeserializeCommitEventDataAsync(
rpcClient,
network,
contractAddress,
id,
accountForSimulation);

Expand Down Expand Up @@ -106,7 +114,7 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(

if (isLockEvent)
{
var prefixPattern = "Program return: " + htlcTokenContractAddress + " ";
var prefixPattern = "Program return: " + contractAddress + " ";

var logResult = transaction.Meta.LogMessages.Where(s => s.StartsWith(prefixPattern))
.Select(s => s.Substring(prefixPattern.Length))
Expand All @@ -118,6 +126,7 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(
var addLockMessageResult = await DeserializeAddLockEventDataAsync(
rpcClient,
network,
contractAddress,
id,
accountForSimulation);

Expand All @@ -139,6 +148,7 @@ public static async Task<HTLCBlockEventResponse> GetBlockEventsAsync(
private static async Task<SolanaHTLCCommitEventModel> DeserializeCommitEventDataAsync(
IRpcClient rpcClient,
DetailedNetworkDto network,
string contractAddress,
string commitId,
string solverAccount)
{
Expand All @@ -152,7 +162,7 @@ private static async Task<SolanaHTLCCommitEventModel> DeserializeCommitEventData
.SetFeePayer(new PublicKey(solverAccount));

builder.SetGetDetailsInstruction(
new PublicKey(network.HTLCTokenContractAddress),
new PublicKey(contractAddress),
commitId.HexToByteArray());

var latestBlockHashResponse = await rpcClient.GetLatestBlockHashAsync();
Expand Down Expand Up @@ -191,6 +201,7 @@ private static async Task<SolanaHTLCCommitEventModel> DeserializeCommitEventData
private static async Task<HTLCLockEventMessage?> DeserializeAddLockEventDataAsync(
IRpcClient rpcClient,
DetailedNetworkDto network,
string contractAddress,
string commitId,
string solverAccount)
{
Expand All @@ -205,10 +216,8 @@ private static async Task<SolanaHTLCCommitEventModel> DeserializeCommitEventData
var builder = new TransactionBuilder()
.SetFeePayer(new PublicKey(solverAccount));

var htlcContractAddress = network.HTLCTokenContractAddress;

builder.SetGetDetailsInstruction(
new PublicKey(htlcContractAddress),
new PublicKey(contractAddress),
commitId.HexToByteArray());

var latestBlockHashResponse = await rpcClient.GetLatestBlockHashAsync();
Expand Down
121 changes: 77 additions & 44 deletions csharp/src/Workflow.Solana/Helpers/SolanaTransactionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
using Train.Solver.Workflow.Abstractions.Models;
using Train.Solver.Workflow.Solana.Programs.HTLCProgram;
using Train.Solver.Workflow.Solana.Programs.HTLCProgram.Models;
using Train.Solver.Workflow.Solana.Programs.HtlcSolProgram;
using Train.Solver.Workflow.Solana.Programs.HtlcSolProgram.Models;
using Train.Solver.Workflow.Solana.Programs.HtlcSplProgram.Models;

namespace Train.Solver.Workflow.Solana.Helpers;

Expand Down Expand Up @@ -59,18 +62,11 @@ public static async Task<PrepareTransactionDto> BuildHTLCLockTransactionAsync(
var builder = new TransactionBuilder()
.SetFeePayer(new PublicKey(solverAccount));

await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(solverAccount),
new PublicKey(solverAccount));

if (isNative)
{
builder.SetSolLockTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCSplLockRequest
new HTLCSolLockRequest
{
Id = request.CommitId.HexToByteArray(),
Hashlock = request.Hashlock.HexToByteArray(),
Expand All @@ -88,6 +84,13 @@ await GetOrCreateAssociatedTokenAccount(
}
else
{
await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(solverAccount),
new PublicKey(solverAccount));

builder.SetSplLockTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCSplLockRequest
Expand Down Expand Up @@ -183,27 +186,43 @@ public static async Task<PrepareTransactionDto> BuildHTLCRedeemTransactionAsync(
var builder = new TransactionBuilder()
.SetFeePayer(new PublicKey(solverAccount));

await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(solverAccount),
new PublicKey(solverAccount));
if (isNative)
{
builder.SetSolRedeemTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCSolRedeemRequest
{
Id = request.CommitId.HexToByteArray(),
Secret = BigInteger.Parse(request.Secret).ToHexBigInteger().HexValue.HexToByteArray(),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress),
SenderPublicKey = new PublicKey(request.SenderAddress),
});
}
else
{
await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(solverAccount),
new PublicKey(solverAccount));

builder.SetRedeemTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCRedeemRequest
{
Id = request.CommitId.HexToByteArray(),
Secret = BigInteger.Parse(request.Secret).ToHexBigInteger().HexValue.HexToByteArray(),
SourceTokenPublicKey = new PublicKey(currency.Contract),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress),
SenderPublicKey = new PublicKey(request.SenderAddress),
RewardPublicKey = request.DestinationAddress == solverAccount ?
new PublicKey(request.DestinationAddress) :
new PublicKey(request.SenderAddress),
});
builder.SetSplRedeemTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCSplRedeemRequest
{
Id = request.CommitId.HexToByteArray(),
Secret = BigInteger.Parse(request.Secret).ToHexBigInteger().HexValue.HexToByteArray(),
SourceTokenPublicKey = new PublicKey(currency.Contract),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress),
SenderPublicKey = new PublicKey(request.SenderAddress),
RewardPublicKey = request.DestinationAddress == solverAccount ?
new PublicKey(request.DestinationAddress) :
new PublicKey(request.SenderAddress),
});
}

var latestBlockResult = await rpcClient.GetLatestBlockHashAsync();

Expand Down Expand Up @@ -268,22 +287,36 @@ public static async Task<PrepareTransactionDto> BuildHTLCRefundTransactionAsync(
var builder = new TransactionBuilder()
.SetFeePayer(new PublicKey(solverAccount));

await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(request.DestinationAddress),
new PublicKey(solverAccount));
if (isNative)
{
builder.SetSolRefundTransactionInstruction(
new PublicKey(htlcContractAddress),
new HtlcSolRefundRequest
{
Id = request.CommitId.HexToByteArray(),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress)
});
}
else
{
await GetOrCreateAssociatedTokenAccount(
rpcClient,
builder,
currency,
new PublicKey(request.DestinationAddress),
new PublicKey(solverAccount));

builder.SetRefundTransactionInstruction(
new PublicKey(htlcContractAddress),
new HTLCRefundRequest
{
Id = request.CommitId.HexToByteArray(),
SourceTokenPublicKey = new PublicKey(currency.Contract),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress)
});
builder.SetSplRefundTransactionInstruction(
new PublicKey(htlcContractAddress),
new HtlcSplRefundRequest
{
Id = request.CommitId.HexToByteArray(),
SourceTokenPublicKey = new PublicKey(currency.Contract),
SignerPublicKey = new PublicKey(solverAccount),
ReceiverPublicKey = new PublicKey(request.DestinationAddress)
});
}

var latestBlockHashResponse = await rpcClient.GetLatestBlockHashAsync();

Expand Down Expand Up @@ -422,7 +455,7 @@ public static async Task<PrepareTransactionDto> BuildHTLCAddlockSigTransactionAs

builder.SetAddLockSigInstruction(
new PublicKey(htlcContractAddress),
new HTLCAddlocksigRequest
new HtlcAddlocksigRequest
{
AddLockSigMessageRequest = new()
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using Solnet.Rpc.Builders;
using Solnet.Wallet;
using Train.Solver.Workflow.Solana.Programs.HtlcSolProgram.Models;

namespace Train.Solver.Workflow.Solana.Programs.HtlcSolProgram;

public static class HtlcSolProgram
{
public static TransactionBuilder SetSolLockTransactionInstruction(
this TransactionBuilder builder,
PublicKey htlcProgramIdKey,
HTLCSolLockRequest htlcLockRequest)
{
var pdaParams = GetSolHtlcPdaParams(htlcLockRequest.Id, htlcProgramIdKey);

var lockData = new HtlcSolInstructionDataBuilder().CreateSolLockData(htlcLockRequest);
var lockRewardData = new HtlcSolInstructionDataBuilder().CreateLockRewardData(htlcLockRequest);

builder.AddInstruction(new()
{
ProgramId = htlcProgramIdKey,
Keys = HtlcSolInstructionKeyProvider.CreateSolLockAccountKeys(htlcLockRequest, pdaParams),
Data = lockData
});

builder.AddInstruction(new()
{
ProgramId = htlcProgramIdKey,
Keys = HtlcSolInstructionKeyProvider.CreateSolLockRewardAccountKeys(htlcLockRequest, pdaParams),
Data = lockRewardData
});
return builder;
}

public static TransactionBuilder SetSolRedeemTransactionInstruction(
this TransactionBuilder builder,
PublicKey htlcProgramIdKey,
HTLCSolRedeemRequest redeemRequest)
{
var pdaParams = GetSolHtlcPdaParams(redeemRequest.Id, htlcProgramIdKey);

var redeemData = new HtlcSolInstructionDataBuilder().CreateSolRedeemData(redeemRequest);

builder.AddInstruction(new()
{
ProgramId = htlcProgramIdKey,
Keys = HtlcSolInstructionKeyProvider.CreateSolRedeemAccountKeys(redeemRequest, pdaParams),
Data = redeemData
});

return builder;
}

public static TransactionBuilder SetSolRefundTransactionInstruction(
this TransactionBuilder builder,
PublicKey htlcProgramIdKey,
HtlcSolRefundRequest htlcRefundRequest)
{
var pdaParams = GetSolHtlcPdaParams(htlcRefundRequest.Id, htlcProgramIdKey);

var refundData = new HtlcSolInstructionDataBuilder().CreateSolRefundData(htlcRefundRequest);

builder.AddInstruction(new()
{
ProgramId = htlcProgramIdKey,
Keys = HtlcSolInstructionKeyProvider.SetSolRefundAccountKeys(htlcRefundRequest, pdaParams),
Data = refundData
});

return builder;
}

private static HtlcSolPdaResponse GetSolHtlcPdaParams(
byte[] Id,
PublicKey htlcProgramIdKey)
{
var htlc = PublicKey.TryFindProgramAddress(
new List<byte[]>()
{
Id
},
htlcProgramIdKey,
out PublicKey htlcPubKey,
out _);

return new()
{
HtlcPublicKey = htlcPubKey
};
}
}
Loading