diff --git a/src/Solnet.Examples/TokenSwapExample.cs b/src/Solnet.Examples/TokenSwapExample.cs
index 542beebd..e04e9e59 100644
--- a/src/Solnet.Examples/TokenSwapExample.cs
+++ b/src/Solnet.Examples/TokenSwapExample.cs
@@ -22,6 +22,12 @@ public class TokenSwapExample : IExample
public void Run()
{
+ //how to load current state
+ IRpcClient mainnetRpc = ClientFactory.GetClient(Cluster.MainNet);
+ var resp = mainnetRpc.GetAccountInfo("GAM8dQkm4LwYJgPZbML61mKPUCQX7uAquxu67p9oifSK");
+ var obj = TokenSwapAccount.Deserialize(Convert.FromBase64String(resp.Result.Value.Data[0]));
+ Console.WriteLine($"Pool Mint: {obj.PoolMint}");
+
Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords);
var tokenAMint = new Account();
@@ -99,7 +105,8 @@ public void Run()
Examples.PollConfirmedTx(txSig);
var swap = new Account();
- var program = new TokenSwapProgram(swap);
+ var program = new TokenSwapProgram();
+ var swapAuthority = program.CreateAuthority(swap).pubkey;
var swapTokenAAccount= new Account();
var swapTokenBAccount = new Account();
@@ -119,7 +126,7 @@ public void Run()
.AddInstruction(TokenProgram.InitializeAccount(
swapTokenAAccount,
tokenAMint,
- program.SwapAuthority
+ swapAuthority
))
.AddInstruction(TokenProgram.Transfer(
tokenAUserAccount,
@@ -137,7 +144,7 @@ public void Run()
.AddInstruction(TokenProgram.InitializeAccount(
swapTokenBAccount,
tokenBMint,
- program.SwapAuthority
+ swapAuthority
))
.AddInstruction(TokenProgram.Transfer(
tokenBUserAccount,
@@ -168,7 +175,7 @@ public void Run()
.AddInstruction(TokenProgram.InitializeMint(
poolMint,
9,
- program.SwapAuthority
+ swapAuthority
))
.AddInstruction(SystemProgram.CreateAccount(
wallet.Account,
@@ -206,11 +213,12 @@ public void Run()
.AddInstruction(SystemProgram.CreateAccount(
wallet.Account,
swap,
- RpcClient.GetMinimumBalanceForRentExemption((long)program.TokenSwapAccountDataSize).Result,
- program.TokenSwapAccountDataSize,
+ RpcClient.GetMinimumBalanceForRentExemption((long)TokenSwapProgram.TokenSwapAccountDataSize).Result,
+ TokenSwapProgram.TokenSwapAccountDataSize,
program.ProgramIdKey
))
.AddInstruction(program.Initialize(
+ swap,
swapTokenAAccount,
swapTokenBAccount,
poolMint,
@@ -231,7 +239,7 @@ public void Run()
))
.Build(new Account[] { wallet.Account, swap });
Console.WriteLine($"Swap Account: {swap}");
- Console.WriteLine($"Swap Auth Account: {program.SwapAuthority}");
+ Console.WriteLine($"Swap Auth Account: {swapAuthority}");
Console.WriteLine($"Pool Mint Account: {poolMint}");
Console.WriteLine($"Pool User Account: {poolUserAccount}");
Console.WriteLine($"Pool Fee Account: {poolFeeAccount}");
@@ -244,6 +252,7 @@ public void Run()
.SetRecentBlockHash(blockHash.Result.Value.Blockhash)
.SetFeePayer(wallet.Account)
.AddInstruction(program.Swap(
+ swap,
wallet.Account,
tokenAUserAccount,
swapTokenAAccount,
@@ -264,6 +273,7 @@ public void Run()
.SetRecentBlockHash(blockHash.Result.Value.Blockhash)
.SetFeePayer(wallet.Account)
.AddInstruction(program.DepositAllTokenTypes(
+ swap,
wallet.Account,
tokenAUserAccount,
tokenBUserAccount,
@@ -284,6 +294,7 @@ public void Run()
.SetRecentBlockHash(blockHash.Result.Value.Blockhash)
.SetFeePayer(wallet.Account)
.AddInstruction(program.WithdrawAllTokenTypes(
+ swap,
wallet.Account,
poolMint,
poolUserAccount,
@@ -305,6 +316,7 @@ public void Run()
.SetRecentBlockHash(blockHash.Result.Value.Blockhash)
.SetFeePayer(wallet.Account)
.AddInstruction(program.DepositSingleTokenTypeExactAmountIn(
+ swap,
wallet.Account,
tokenAUserAccount,
swapTokenAAccount,
@@ -323,6 +335,7 @@ public void Run()
.SetRecentBlockHash(blockHash.Result.Value.Blockhash)
.SetFeePayer(wallet.Account)
.AddInstruction(program.WithdrawSingleTokenTypeExactAmountOut(
+ swap,
wallet.Account,
poolMint,
poolUserAccount,
diff --git a/src/Solnet.Programs/Abstract/BaseProgram.cs b/src/Solnet.Programs/Abstract/BaseProgram.cs
new file mode 100644
index 00000000..1614d868
--- /dev/null
+++ b/src/Solnet.Programs/Abstract/BaseProgram.cs
@@ -0,0 +1,39 @@
+using Solnet.Wallet;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Solnet.Programs.Abstract
+{
+ ///
+ /// A class to abstract some of the core program commonality
+ ///
+ public abstract class BaseProgram : Program
+ {
+ private PublicKey _programIdKey;
+ private string _programName;
+
+ ///
+ /// The public key of the program.
+ ///
+ public virtual PublicKey ProgramIdKey => _programIdKey;
+
+ ///
+ /// The program's name.
+ ///
+ public virtual string ProgramName => _programName;
+
+ ///
+ /// Creates an instance of the base program class with specified id and name
+ ///
+ /// The program key
+ /// The program name
+ protected BaseProgram(PublicKey programIdKey, string programName)
+ {
+ _programIdKey = programIdKey;
+ _programName = programName;
+ }
+ }
+}
diff --git a/src/Solnet.Programs/Abstract/Program.cs b/src/Solnet.Programs/Abstract/Program.cs
new file mode 100644
index 00000000..94067343
--- /dev/null
+++ b/src/Solnet.Programs/Abstract/Program.cs
@@ -0,0 +1,21 @@
+using Solnet.Wallet;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Solnet.Programs.Abstract
+{
+ public interface Program
+ {
+ ///
+ /// The program's key
+ ///
+ PublicKey ProgramIdKey { get; }
+ ///
+ /// The name of the program
+ ///
+ string ProgramName { get; }
+ }
+}
diff --git a/src/Solnet.Programs/TokenSwap/Models/Fees.cs b/src/Solnet.Programs/TokenSwap/Models/Fees.cs
index 91651287..c2cf13e1 100644
--- a/src/Solnet.Programs/TokenSwap/Models/Fees.cs
+++ b/src/Solnet.Programs/TokenSwap/Models/Fees.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers.Binary;
using Solnet.Programs.Utilities;
namespace Solnet.Programs.TokenSwap.Models
@@ -65,5 +66,22 @@ public Span Serialize()
ret.WriteU64(HostFeeDenomerator, 56);
return new Span(ret);
}
+
+ public static Fees Deserialize(byte[] bytes)
+ {
+ var span = new Span(bytes);
+ var f = new Fees()
+ {
+ TradeFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(0, 8)),
+ TradeFeeDenominator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(8, 8)),
+ OwnerTradeFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(16, 8)),
+ OwnerTradeFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(24, 8)),
+ OwnerWithrawFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(32, 8)),
+ OwnerWithrawFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(40, 8)),
+ HostFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(48, 8)),
+ HostFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(56, 8)),
+ };
+ return f;
+ }
}
}
diff --git a/src/Solnet.Programs/TokenSwap/Models/SwapCurve.cs b/src/Solnet.Programs/TokenSwap/Models/SwapCurve.cs
index 9504a996..3f86d187 100644
--- a/src/Solnet.Programs/TokenSwap/Models/SwapCurve.cs
+++ b/src/Solnet.Programs/TokenSwap/Models/SwapCurve.cs
@@ -1,5 +1,6 @@
using Solnet.Programs.Utilities;
using System;
+using System.Buffers.Binary;
namespace Solnet.Programs.TokenSwap.Models
{
@@ -8,6 +9,11 @@ namespace Solnet.Programs.TokenSwap.Models
///
public class SwapCurve
{
+ ///
+ /// The constant procuct curve
+ ///
+ public static SwapCurve ConstantProduct => new SwapCurve() { CurveType = CurveType.ConstantProduct, Calculator = new ConstantProductCurve() };
+
///
/// The curve type.
///
@@ -35,9 +41,19 @@ public virtual ReadOnlySpan Serialize()
return new Span(ret);
}
- ///
- /// The constant procuct curve
- ///
- public static SwapCurve ConstantProduct => new SwapCurve() { CurveType = CurveType.ConstantProduct, Calculator = new ConstantProductCurve() };
+ public static SwapCurve Deserialize(byte[] bytes)
+ {
+ var s = new SwapCurve()
+ {
+ CurveType = (CurveType)bytes[0],
+ //todo other curves
+ Calculator = new ConstantProductCurve()
+ };
+ if (s.CurveType != CurveType.ConstantProduct)
+ {
+ throw new NotSupportedException("Only constant product curves are supported by Solnet currently");
+ }
+ return s;
+ }
}
}
diff --git a/src/Solnet.Programs/TokenSwap/Models/TokenSwapAccount.cs b/src/Solnet.Programs/TokenSwap/Models/TokenSwapAccount.cs
new file mode 100644
index 00000000..e4cbf5e2
--- /dev/null
+++ b/src/Solnet.Programs/TokenSwap/Models/TokenSwapAccount.cs
@@ -0,0 +1,115 @@
+using Solnet.Wallet;
+
+namespace Solnet.Programs.TokenSwap.Models
+{
+
+ ///
+ /// TokenSwap program state
+ ///
+ public class TokenSwapAccount
+ {
+ ///
+ /// the size of this account in bytes
+ ///
+ public const int TOKEN_SWAP_DATA_LEN = 324;
+
+ ///
+ /// Versions of this state account
+ ///
+ public enum SwapVersion { SwapV1 = 1 }
+
+ ///
+ /// Version of this state account
+ ///
+ public SwapVersion Version;
+
+ ///
+ /// Initialized state
+ ///
+ public bool IsInitialized;
+
+ ///
+ /// Nonce used in program address.
+ /// The program address is created deterministically with the nonce,
+ /// swap program id, and swap account pubkey. This program address has
+ /// authority over the swap's token A account, token B account, and pool
+ /// token mint.
+ ///
+ public byte Nonce;
+
+ ///
+ /// Program ID of the tokens being exchanged.
+ ///
+ public PublicKey TokenProgramId;
+
+ ///
+ /// Token A
+ ///
+ public PublicKey TokenAAccount;
+
+ ///
+ /// Token B
+ ///
+ public PublicKey TokenBAccount;
+
+ ///
+ /// Pool tokens are issued when A or B tokens are deposited.
+ /// Pool tokens can be withdrawn back to the original A or B token.
+ ///
+ public PublicKey PoolMint;
+
+ ///
+ /// Mint information for token A
+ ///
+ public PublicKey TokenAMint;
+
+ ///
+ /// Mint information for token B
+ ///
+ public PublicKey TokenBMint;
+
+ ///
+ /// Pool token account to receive trading and / or withdrawal fees
+ ///
+ public PublicKey PoolFeeAccount;
+
+ ///
+ /// All fee information
+ ///
+ public Fees Fees;
+
+ ///
+ /// Swap curve parameters, to be unpacked and used by the SwapCurve, which
+ /// calculates swaps, deposits, and withdrawals
+ ///
+ public SwapCurve SwapCurve;
+
+ ///
+ /// Deserilize a token swap from the bytes of an account
+ ///
+ ///
+ ///
+ public static TokenSwapAccount Deserialize(byte[] data)
+ {
+ if (data.Length != TOKEN_SWAP_DATA_LEN)
+ return null;
+
+ var ret = new TokenSwapAccount()
+ {
+ Version = SwapVersion.SwapV1,
+ IsInitialized = data[1] == 1,
+ Nonce = data[2],
+ TokenProgramId = new PublicKey(data[3..35]),
+ TokenAAccount = new PublicKey(data[35..67]),
+ TokenBAccount = new PublicKey(data[67..99]),
+ PoolMint = new PublicKey(data[99..131]),
+ TokenAMint = new PublicKey(data[131..163]),
+ TokenBMint = new PublicKey(data[163..195]),
+ PoolFeeAccount = new PublicKey(data[195..227]),
+ Fees = Fees.Deserialize(data[227..291]),
+ SwapCurve = SwapCurve.Deserialize(data[291..]),
+ };
+ return ret;
+ }
+ }
+}
diff --git a/src/Solnet.Programs/TokenSwap/TokenSwapProgram.cs b/src/Solnet.Programs/TokenSwap/TokenSwapProgram.cs
index d0ccb683..86a32093 100644
--- a/src/Solnet.Programs/TokenSwap/TokenSwapProgram.cs
+++ b/src/Solnet.Programs/TokenSwap/TokenSwapProgram.cs
@@ -1,3 +1,4 @@
+using Solnet.Programs.Abstract;
using Solnet.Programs.TokenSwap.Models;
using Solnet.Programs.Utilities;
using Solnet.Rpc.Models;
@@ -16,7 +17,7 @@ namespace Solnet.Programs.TokenSwap
/// https://docs.rs/spl-token-swap/2.1.0/spl_token_swap/
///
///
- public class TokenSwapProgram
+ public class TokenSwapProgram : BaseProgram
{
///
/// SPL Token Swap Program Program ID
@@ -26,17 +27,10 @@ public class TokenSwapProgram
///
/// SPL Token Swap Program Program Name
///
- public static readonly string TokenSwapProgramProgramName = "Token Swap Program";
+ public static readonly string TokenSwapProgramName = "Token Swap Program";
- ///
- /// The public key of the Token Swap Program.
- ///
- public virtual PublicKey ProgramIdKey => TokenSwapProgramIdKey;
-
- ///
- /// The program's name.
- ///
- public virtual string ProgramName => TokenSwapProgramProgramName;
+
+ //instance vars
///
/// The owner key required to use as the fee account owner.
@@ -46,40 +40,27 @@ public class TokenSwapProgram
///
/// Token Swap account layout size.
///
- public virtual ulong TokenSwapAccountDataSize => 324;
-
- ///
- /// Exposes the computed swap authority public key. Subclasses can override CreateAuthority to change the value.
- ///
- public PublicKey SwapAuthority => _swapAuthority;
-
+ public static readonly ulong TokenSwapAccountDataSize = 323;
+
///
- /// Exposes the computed swap authority public key
+ /// Create a token swap program instance with the standard programid and program name
///
- public byte SwapAuthorityNonce => _nonce;
-
- private readonly PublicKey _tokenSwapAccount;
- private readonly PublicKey _swapAuthority;
- private readonly byte _nonce;
+ public TokenSwapProgram() : base(TokenSwapProgramIdKey, TokenSwapProgramName) { }
///
- /// Create a new instance to operation over the specified token swap
+ /// Create a token swap program instance with a custom programid
///
- /// The token swap that operations will be made over
- public TokenSwapProgram(PublicKey tokenSwapAccount)
- {
- _tokenSwapAccount = tokenSwapAccount;
- (_swapAuthority, _nonce) = CreateAuthority();
- }
+ /// The program id to use
+ public TokenSwapProgram(PublicKey programId) : base(programId, TokenSwapProgramName) { }
///
/// Create the authority
///
/// The swap authority
/// No program account could be found (exhausted nonces)
- protected virtual (PublicKey, byte) CreateAuthority()
+ public virtual (PublicKey pubkey, byte nonce) CreateAuthority(PublicKey tokenSwapAccount)
{
- if (!AddressExtensions.TryFindProgramAddress(new[] { _tokenSwapAccount.KeyBytes }, ProgramIdKey.KeyBytes, out var addressBytes, out var nonce))
+ if (!AddressExtensions.TryFindProgramAddress(new[] { tokenSwapAccount.KeyBytes }, ProgramIdKey.KeyBytes, out var addressBytes, out var nonce))
throw new InvalidProgramException();
var auth = new PublicKey(addressBytes);
return (auth, (byte)nonce);
@@ -88,6 +69,7 @@ protected virtual (PublicKey, byte) CreateAuthority()
///
/// Initializes a new swap.
///
+ /// The token swap account to initialize.
/// token_a Account. Must be non zero, owned by swap authority.
/// token_b Account. Must be non zero, owned by swap authority.
/// Pool Token Mint. Must be empty, owned by swap authority.
@@ -97,6 +79,7 @@ protected virtual (PublicKey, byte) CreateAuthority()
/// Curve to use for this token swap.
/// The transaction instruction.
public virtual TransactionInstruction Initialize(
+ PublicKey tokenSwapAccount,
PublicKey tokenAAccount,
PublicKey tokenBAccount,
PublicKey poolTokenMint,
@@ -104,10 +87,11 @@ public virtual TransactionInstruction Initialize(
PublicKey userPoolTokenAccount,
Fees fees, SwapCurve swapCurve)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.Writable(_tokenSwapAccount, true),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.Writable(tokenSwapAccount, true),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(tokenAAccount, false),
AccountMeta.ReadOnly(tokenBAccount, false),
AccountMeta.Writable(poolTokenMint, false),
@@ -119,13 +103,14 @@ public virtual TransactionInstruction Initialize(
{
ProgramId = ProgramIdKey.KeyBytes,
Keys = keys,
- Data = TokenSwapProgramData.EncodeInitializeData(_nonce, fees, swapCurve)
+ Data = TokenSwapProgramData.EncodeInitializeData(nonce, fees, swapCurve)
};
}
///
/// Swap the tokens in the pool.
///
+ /// The token swap account to operate over.
/// user transfer authority.
/// token_(A|B) SOURCE Account, amount is transferable by user transfer authority.
/// token_(A|B) Base Account to swap INTO. Must be the SOURCE token.
@@ -138,6 +123,7 @@ public virtual TransactionInstruction Initialize(
/// Minimum amount of DESTINATION token to output, prevents excessive slippage.
/// The transaction instruction.
public virtual TransactionInstruction Swap(
+ PublicKey tokenSwapAccount,
PublicKey userTransferAuthority,
PublicKey tokenSourceAccount,
PublicKey tokenBaseIntoAccount,
@@ -148,10 +134,11 @@ public virtual TransactionInstruction Swap(
PublicKey poolTokenHostFeeAccount,
ulong amountIn, ulong amountOut)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.ReadOnly(_tokenSwapAccount, false),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.ReadOnly(tokenSwapAccount, false),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(userTransferAuthority, false),
AccountMeta.Writable(tokenSourceAccount, false),
AccountMeta.Writable(tokenBaseIntoAccount, false),
@@ -178,6 +165,7 @@ public virtual TransactionInstruction Swap(
/// token representing ownership in the pool. Inputs are converted to
/// the current ratio.
///
+ /// The token swap account to operate over.
/// user transfer authority.
/// token_a - user transfer authority can transfer amount.
/// token_b - user transfer authority can transfer amount.
@@ -190,6 +178,7 @@ public virtual TransactionInstruction Swap(
/// Maximum token B amount to deposit, prevents excessive slippage.
/// The transaction instruction.
public virtual TransactionInstruction DepositAllTokenTypes(
+ PublicKey tokenSwapAccount,
PublicKey userTransferAuthority,
PublicKey tokenAuserAccount,
PublicKey tokenBuserAccount,
@@ -199,10 +188,11 @@ public virtual TransactionInstruction DepositAllTokenTypes(
PublicKey poolTokenUserAccount,
ulong poolTokenAmount, ulong maxTokenA, ulong maxTokenB)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.ReadOnly(_tokenSwapAccount, false),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.ReadOnly(tokenSwapAccount, false),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(userTransferAuthority, false),
AccountMeta.Writable(tokenAuserAccount, false),
AccountMeta.Writable(tokenBuserAccount, false),
@@ -225,6 +215,7 @@ public virtual TransactionInstruction DepositAllTokenTypes(
/// pool tokens. The pool tokens are burned in exchange for an equivalent
/// amount of token A and B.
///
+ /// The token swap account to operate over.
/// user transfer authority.
/// Pool MINT account, swap authority is the owner.
/// SOURCE Pool account, amount is transferable by user transfer authority.
@@ -238,6 +229,7 @@ public virtual TransactionInstruction DepositAllTokenTypes(
/// Minimum amount of token B to receive, prevents excessive slippage.
/// The transaction instruction.
public virtual TransactionInstruction WithdrawAllTokenTypes(
+ PublicKey tokenSwapAccount,
PublicKey userTransferAuthority,
PublicKey poolTokenMint,
PublicKey sourcePoolAccount,
@@ -248,10 +240,11 @@ public virtual TransactionInstruction WithdrawAllTokenTypes(
PublicKey feeAccount,
ulong poolTokenAmount, ulong minTokenA, ulong minTokenB)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.ReadOnly(_tokenSwapAccount, false),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.ReadOnly(tokenSwapAccount, false),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(userTransferAuthority, false),
AccountMeta.Writable(poolTokenMint, false),
AccountMeta.Writable(sourcePoolAccount, false),
@@ -275,6 +268,7 @@ public virtual TransactionInstruction WithdrawAllTokenTypes(
/// representing ownership into the pool. Input token is converted as if
/// a swap and deposit all token types were performed.
///
+ /// The token swap account to operate over.
/// user transfer authority.
/// token_(A|B) SOURCE Account, amount is transferable by user transfer authority.
/// token_a Swap Account, may deposit INTO.
@@ -285,6 +279,7 @@ public virtual TransactionInstruction WithdrawAllTokenTypes(
/// Pool token amount to receive in exchange. The amount is set by the current exchange rate and size of the pool.
/// The transaction instruction.
public virtual TransactionInstruction DepositSingleTokenTypeExactAmountIn(
+ PublicKey tokenSwapAccount,
PublicKey userTransferAuthority,
PublicKey sourceAccount,
PublicKey destinationTokenAAccount,
@@ -293,10 +288,11 @@ public virtual TransactionInstruction DepositSingleTokenTypeExactAmountIn(
PublicKey poolTokenUserAccount,
ulong sourceTokenAmount, ulong minPoolTokenAmount)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.ReadOnly(_tokenSwapAccount, false),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.ReadOnly(tokenSwapAccount, false),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(userTransferAuthority, false),
AccountMeta.Writable(sourceAccount, false),
AccountMeta.Writable(destinationTokenAAccount, false),
@@ -317,6 +313,7 @@ public virtual TransactionInstruction DepositSingleTokenTypeExactAmountIn(
/// Withdraw one token type from the pool at the current ratio given the
/// exact amount out expected.
///
+ /// The token swap account to operate over.
/// user transfer authority.
/// Pool mint account, swap authority is the owner.
/// SOURCE Pool account, amount is transferable by user transfer authority.
@@ -328,6 +325,7 @@ public virtual TransactionInstruction DepositSingleTokenTypeExactAmountIn(
/// Maximum amount of pool tokens to burn. User receives an output of token A or B based on the percentage of the pool tokens that are returned.
/// The transaction instruction.
public virtual TransactionInstruction WithdrawSingleTokenTypeExactAmountOut(
+ PublicKey tokenSwapAccount,
PublicKey userTransferAuthority,
PublicKey poolMintAccount,
PublicKey sourceUserAccount,
@@ -337,10 +335,11 @@ public virtual TransactionInstruction WithdrawSingleTokenTypeExactAmountOut(
PublicKey feeAccount,
ulong destTokenAmount, ulong maxPoolTokenAmount)
{
+ var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount);
List keys = new()
{
- AccountMeta.ReadOnly(_tokenSwapAccount, false),
- AccountMeta.ReadOnly(_swapAuthority, false),
+ AccountMeta.ReadOnly(tokenSwapAccount, false),
+ AccountMeta.ReadOnly(swapAuthority, false),
AccountMeta.ReadOnly(userTransferAuthority, false),
AccountMeta.Writable(poolMintAccount, false),
AccountMeta.Writable(sourceUserAccount, false),
@@ -375,7 +374,7 @@ public static DecodedInstruction Decode(ReadOnlySpan data, IList(),
InnerInstructions = new List()
};
diff --git a/test/Solnet.Programs.Test/TokenSwapProgramTest.cs b/test/Solnet.Programs.Test/TokenSwapProgramTest.cs
index e59b313e..da7a85e1 100644
--- a/test/Solnet.Programs.Test/TokenSwapProgramTest.cs
+++ b/test/Solnet.Programs.Test/TokenSwapProgramTest.cs
@@ -130,7 +130,8 @@ public void TestInitialize()
var poolFee = wallet.GetAccount(6);
var poolToken = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).Initialize(
+ var txInstruction = new TokenSwapProgram().Initialize(
+ tokenSwapAccount,
tokenA.PublicKey,
tokenB.PublicKey,
poolMint.PublicKey,
@@ -170,7 +171,8 @@ public void TestSwap()
var fee = wallet.GetAccount(7);
var hostFee = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).Swap(
+ var txInstruction = new TokenSwapProgram().Swap(
+ tokenSwapAccount,
userXfer.PublicKey,
source.PublicKey,
into.PublicKey,
@@ -202,7 +204,8 @@ public void TestDepositAllTokenTypes()
var poolTokenMint = wallet.GetAccount(7);
var poolAccount = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).DepositAllTokenTypes(
+ var txInstruction = new TokenSwapProgram().DepositAllTokenTypes(
+ tokenSwapAccount,
userXfer.PublicKey,
authA.PublicKey,
authB.PublicKey,
@@ -235,7 +238,8 @@ public void TestWithdrawAllTokenTypes()
var tokenBTo = wallet.GetAccount(7);
var feeAccount = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).WithdrawAllTokenTypes(
+ var txInstruction = new TokenSwapProgram().WithdrawAllTokenTypes(
+ tokenSwapAccount,
userXfer.PublicKey,
poolTokenMint.PublicKey,
sourcePoolAccount.PublicKey,
@@ -267,7 +271,8 @@ public void TestDepositSingleTokenTypeExactAmountInTypes()
var poolMint = wallet.GetAccount(7);
var pool = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).DepositSingleTokenTypeExactAmountIn(
+ var txInstruction = new TokenSwapProgram().DepositSingleTokenTypeExactAmountIn(
+ tokenSwapAccount,
userXfer.PublicKey,
tokenSource.PublicKey,
tokenA.PublicKey,
@@ -297,7 +302,8 @@ public void TestWithdrawSingleTokenTypeExactAmountOutTypes()
var userToken = wallet.GetAccount(7);
var feeAccount = wallet.GetAccount(7);
- var txInstruction = new TokenSwapProgram(tokenSwapAccount).WithdrawSingleTokenTypeExactAmountOut(
+ var txInstruction = new TokenSwapProgram().WithdrawSingleTokenTypeExactAmountOut(
+ tokenSwapAccount,
userXfer.PublicKey,
poolMint.PublicKey,
sourcePool.PublicKey,