diff --git a/SharedBuildProperties.props b/SharedBuildProperties.props index 6889d31..fed1fe0 100644 --- a/SharedBuildProperties.props +++ b/SharedBuildProperties.props @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> Solnet.Serum - 1.1.1 + 1.2.0 Copyright 2021 © Solnet blockmountain blockmountain diff --git a/Solnet.Serum.Examples/CloseOpenOrdersExample.cs b/Solnet.Serum.Examples/CloseOpenOrdersExample.cs index 5f125c6..53084d6 100644 --- a/Solnet.Serum.Examples/CloseOpenOrdersExample.cs +++ b/Solnet.Serum.Examples/CloseOpenOrdersExample.cs @@ -22,12 +22,14 @@ public class CloseOpenOrdersExample : IRunnableExample private readonly IMarketManager _marketManager; private readonly Wallet.Wallet _wallet; private readonly SolanaKeyStoreService _keyStore; + private readonly SerumProgram _serum; public CloseOpenOrdersExample() { Console.WriteLine($"Initializing {ToString()}"); // init stuff _keyStore = new SolanaKeyStoreService(); + _serum = SerumProgram.CreateMainNet(); // get the wallet _wallet = _keyStore.RestoreKeystoreFromFile("/path/to/wallet.json"); @@ -74,7 +76,7 @@ public async Task CloseAllOpenOrders() new MemCmp { Offset = 45, Bytes = _wallet.Account.PublicKey } }; RequestResult> accounts = await - _serumClient.RpcClient.GetProgramAccountsAsync(SerumProgram.ProgramIdKey, + _serumClient.RpcClient.GetProgramAccountsAsync(SerumProgram.MainNetProgramIdKeyV3, dataSize: OpenOrdersAccount.Layout.SpanLength, memCmpList: filters); Console.WriteLine($"Found {accounts.Result.Count} open orders account for market {_marketAddress}"); @@ -88,13 +90,13 @@ public async Task CloseAllOpenOrders() var txBytes = new TransactionBuilder() .SetFeePayer(_wallet.Account) .SetRecentBlockHash(blockhash.Result.Value.Blockhash) - .AddInstruction(SerumProgram.SettleFunds( + .AddInstruction(_serum.SettleFunds( _marketManager.Market, new (openOrdersAccount.PublicKey), _wallet.Account, _marketManager.BaseTokenAccountAddress, _marketManager.QuoteTokenAccountAddress)) - .AddInstruction(SerumProgram.CloseOpenOrders( + .AddInstruction(_serum.CloseOpenOrders( new (openOrdersAccount.PublicKey), _wallet.Account, _wallet.Account, @@ -125,8 +127,8 @@ public async Task CreateOpenOrders() openOrdersAccount, rentExemption.Result, OpenOrdersAccount.Layout.SpanLength, - SerumProgram.ProgramIdKey)) - .AddInstruction(SerumProgram.InitOpenOrders( + _serum.ProgramIdKey)) + .AddInstruction(_serum.InitOpenOrders( openOrdersAccount, _wallet.Account, _marketAddress)) @@ -167,7 +169,7 @@ public async void Run() var txBytes = new TransactionBuilder() .SetFeePayer(_wallet.Account) .SetRecentBlockHash(blockhash.Result.Value.Blockhash) - .AddInstruction(SerumProgram.CloseOpenOrders( + .AddInstruction(_serum.CloseOpenOrders( _marketManager.OpenOrdersAddress, _wallet.Account, _wallet.Account, _marketAddress)) .CompileMessage(); diff --git a/Solnet.Serum.Examples/ExampleExplorer.cs b/Solnet.Serum.Examples/ExampleExplorer.cs index 7717e26..3d83f2e 100644 --- a/Solnet.Serum.Examples/ExampleExplorer.cs +++ b/Solnet.Serum.Examples/ExampleExplorer.cs @@ -10,7 +10,7 @@ public class ExampleExplorer { public static void Main(string[] args) { - InstructionDecoder.Register(SerumProgram.ProgramIdKey, SerumProgram.Decode); + InstructionDecoder.Register(SerumProgram.MainNetProgramIdKeyV3, SerumProgram.Decode); List examples = Assembly.GetEntryAssembly()?.GetExportedTypes().Where(t => t.IsAssignableTo(typeof(IRunnableExample))).ToList(); if (examples == null) return; diff --git a/Solnet.Serum.Examples/FindOpenOrdersAccounts.cs b/Solnet.Serum.Examples/FindOpenOrdersAccounts.cs index 1c3e731..6fe1624 100644 --- a/Solnet.Serum.Examples/FindOpenOrdersAccounts.cs +++ b/Solnet.Serum.Examples/FindOpenOrdersAccounts.cs @@ -34,7 +34,7 @@ public void Run() new MemCmp{ Offset = 45, Bytes = OwnerAddress } }; RequestResult> accounts = - RpcClient.GetProgramAccounts(SerumProgram.ProgramIdKey, dataSize: OpenOrdersAccount.Layout.SpanLength, memCmpList: filters); + RpcClient.GetProgramAccounts(SerumProgram.MainNetProgramIdKeyV3, dataSize: OpenOrdersAccount.Layout.SpanLength, memCmpList: filters); /* Print all of the found open orders accounts */ foreach (AccountKeyPair account in accounts.Result) diff --git a/Solnet.Serum.Examples/MarketManagerOrdersExample.cs b/Solnet.Serum.Examples/MarketManagerOrdersExample.cs index 383ce03..bcd8381 100644 --- a/Solnet.Serum.Examples/MarketManagerOrdersExample.cs +++ b/Solnet.Serum.Examples/MarketManagerOrdersExample.cs @@ -24,6 +24,7 @@ public class MarketManagerMultipleOrdersExample : IRunnableExample private readonly ISerumClient _serumClient; private readonly IMarketManager _marketManager; private readonly Wallet.Wallet _wallet; + private readonly SerumProgram _serum; private OrderBook _orderBook; private List _bids; private List _asks; @@ -35,6 +36,7 @@ public MarketManagerMultipleOrdersExample() Console.WriteLine($"Initializing {ToString()}"); // init stuff SolanaKeyStoreService keyStore = new (); + _serum = SerumProgram.CreateMainNet(); // get the wallet _wallet = keyStore.RestoreKeystoreFromFile("/path/to/wallet.json"); @@ -133,7 +135,7 @@ private async Task> NewOrdersAsync(IList ord SignatureConfirmation sigConf = null; - TransactionInstruction settleIx = SerumProgram.SettleFunds( + TransactionInstruction settleIx = _serum.SettleFunds( _marketManager.Market, _marketManager.OpenOrdersAddress, _wallet.Account, @@ -144,7 +146,7 @@ private async Task> NewOrdersAsync(IList ord { orders[i].ConvertOrderValues(_marketManager.BaseDecimals, _marketManager.QuoteDecimals, _marketManager.Market); - TransactionInstruction txInstruction = SerumProgram.NewOrderV3( + TransactionInstruction txInstruction = _serum.NewOrderV3( _marketManager.Market, _marketManager.OpenOrdersAddress, orders[i].Side == Side.Buy ? diff --git a/Solnet.Serum.Test/InstructionDecoderTest.cs b/Solnet.Serum.Test/InstructionDecoderTest.cs index 4f4663c..638d079 100644 --- a/Solnet.Serum.Test/InstructionDecoderTest.cs +++ b/Solnet.Serum.Test/InstructionDecoderTest.cs @@ -68,7 +68,7 @@ public class InstructionDecoderTest [ClassInitialize] public static void Setup(TestContext tc) { - InstructionDecoder.Register(SerumProgram.ProgramIdKey, SerumProgram.Decode); + InstructionDecoder.Register(SerumProgram.MainNetProgramIdKeyV3, SerumProgram.Decode); } [TestMethod] diff --git a/Solnet.Serum.Test/MarketManagerTestBase.cs b/Solnet.Serum.Test/MarketManagerTestBase.cs index e8b98e5..067297d 100644 --- a/Solnet.Serum.Test/MarketManagerTestBase.cs +++ b/Solnet.Serum.Test/MarketManagerTestBase.cs @@ -87,7 +87,7 @@ protected void MockGetProgramAccountsAsync(Mock rpcMock, string mark { rpcMock .Setup(s => s.GetProgramAccountsAsync( - It.Is(s1 => s1 == SerumProgram.ProgramIdKey), + It.Is(s1 => s1 == SerumProgram.MainNetProgramIdKeyV3), It.Is(c => c == commitment), It.Is(i => i == OpenOrdersAccount.Layout.SpanLength), It.Is>( diff --git a/Solnet.Serum.Test/SerumProgramTest.cs b/Solnet.Serum.Test/SerumProgramTest.cs index d358213..759580e 100644 --- a/Solnet.Serum.Test/SerumProgramTest.cs +++ b/Solnet.Serum.Test/SerumProgramTest.cs @@ -82,6 +82,7 @@ private static Market GetMarketV3Account() [TestMethod] public void NewOrderV3Test() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); @@ -102,7 +103,7 @@ public void NewOrderV3Test() order.RawQuantity = 10000UL; order.MaxQuoteQuantity = 10000UL; - TransactionInstruction txInstruction = SerumProgram.NewOrderV3( + TransactionInstruction txInstruction = serum.NewOrderV3( market, openOrders.PublicKey, payer.PublicKey, @@ -112,13 +113,14 @@ public void NewOrderV3Test() Assert.AreEqual(12, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedNewOrderV3Data, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void EncodeNewOrderV3Test() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); @@ -147,6 +149,7 @@ public void EncodeNewOrderV3Test() [TestMethod] public void NewOrderV3SerumFeeDiscountTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); @@ -167,7 +170,7 @@ public void NewOrderV3SerumFeeDiscountTest() order.RawQuantity = 10000UL; order.MaxQuoteQuantity = 10000UL; - TransactionInstruction txInstruction = SerumProgram.NewOrderV3( + TransactionInstruction txInstruction = serum.NewOrderV3( market, openOrders.PublicKey, payer.PublicKey, @@ -178,13 +181,14 @@ public void NewOrderV3SerumFeeDiscountTest() Assert.AreEqual(13, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedNewOrderV3SerumFeeData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void SettleFundsInvalidTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); @@ -193,7 +197,7 @@ public void SettleFundsInvalidTest() var quoteW = wallet.GetAccount(4); var referrerPcWallet = wallet.GetAccount(4); - TransactionInstruction txInstruction = SerumProgram.SettleFunds( + TransactionInstruction txInstruction = serum.SettleFunds( market, openOrders, ownerAccount, @@ -208,6 +212,7 @@ public void SettleFundsInvalidTest() [TestMethod] public void SettleFundsTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketV3Account(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); @@ -216,7 +221,7 @@ public void SettleFundsTest() var quoteW = wallet.GetAccount(4); var referrerPcWallet = wallet.GetAccount(4); - TransactionInstruction txInstruction = SerumProgram.SettleFunds( + TransactionInstruction txInstruction = serum.SettleFunds( market, openOrders, ownerAccount, @@ -227,41 +232,41 @@ public void SettleFundsTest() Assert.IsNotNull(txInstruction); Assert.AreEqual(10, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedSettleFundsData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void ConsumeEventsTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); - var ownerAccount = wallet.GetAccount(1); var baseW = wallet.GetAccount(2); var openOrders = wallet.GetAccount(3); var quoteW = wallet.GetAccount(4); - TransactionInstruction txInstruction = SerumProgram.ConsumeEvents( + TransactionInstruction txInstruction = serum.ConsumeEvents( new List{openOrders}, - market.OwnAddress, - ownerAccount, + market, baseW, quoteW, 10); Assert.AreEqual(5, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedConsumeEventsData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void CancelOrderV2Test() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var openOrders = wallet.GetAccount(3); var orderId = new BigInteger(464876397401554404955348M); - TransactionInstruction txInstruction = SerumProgram.CancelOrderV2( + TransactionInstruction txInstruction = serum.CancelOrderV2( market, openOrders, ownerAccount, @@ -270,18 +275,19 @@ public void CancelOrderV2Test() Assert.AreEqual(6, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedCancelOrderV2Data, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void CancelOrderByClientIdV2Test() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var openOrders = wallet.GetAccount(3); - TransactionInstruction txInstruction = SerumProgram.CancelOrderByClientIdV2( + TransactionInstruction txInstruction = serum.CancelOrderByClientIdV2( market, openOrders, ownerAccount, @@ -289,37 +295,39 @@ public void CancelOrderByClientIdV2Test() Assert.AreEqual(6, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedCancelOrderByClientIdV2Data, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void InitOpenOrdersTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var openOrders = wallet.GetAccount(3); - TransactionInstruction txInstruction = SerumProgram.InitOpenOrders( + TransactionInstruction txInstruction = serum.InitOpenOrders( openOrders, ownerAccount, market.OwnAddress); Assert.AreEqual(4, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedInitOpenOrdersData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void InitOpenOrdersMarketAuthorityTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var openOrders = wallet.GetAccount(3); var marketAuthority = wallet.GetAccount(5); - TransactionInstruction txInstruction = SerumProgram.InitOpenOrders( + TransactionInstruction txInstruction = serum.InitOpenOrders( openOrders, ownerAccount, market.OwnAddress, @@ -327,19 +335,20 @@ public void InitOpenOrdersMarketAuthorityTest() Assert.AreEqual(5, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedInitOpenOrdersData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void CloseOpenOrdersTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var openOrders = wallet.GetAccount(3); var refundAccount = wallet.GetAccount(3); - TransactionInstruction txInstruction = SerumProgram.CloseOpenOrders( + TransactionInstruction txInstruction = serum.CloseOpenOrders( openOrders, ownerAccount, refundAccount, @@ -347,19 +356,20 @@ public void CloseOpenOrdersTest() Assert.AreEqual(4, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedCloseOpenOrdersData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } [TestMethod] public void PruneTest() { + var serum = SerumProgram.CreateMainNet(); var market = GetMarketAccount(); var wallet = new Wallet.Wallet(MnemonicWords); var ownerAccount = wallet.GetAccount(1); var pruneAuthority = wallet.GetAccount(2); var openOrders = wallet.GetAccount(3); - TransactionInstruction txInstruction = SerumProgram.Prune( + TransactionInstruction txInstruction = serum.Prune( market, pruneAuthority, openOrders, @@ -367,7 +377,7 @@ public void PruneTest() Assert.AreEqual(7, txInstruction.Keys.Count); CollectionAssert.AreEqual(ExpectedPruneData, txInstruction.Data); - CollectionAssert.AreEqual(SerumProgram.ProgramIdKey.KeyBytes, txInstruction.ProgramId); + CollectionAssert.AreEqual(serum.ProgramIdKey.KeyBytes, txInstruction.ProgramId); } } } \ No newline at end of file diff --git a/Solnet.Serum/MarketManager.cs b/Solnet.Serum/MarketManager.cs index e9ec63a..7abc7a6 100644 --- a/Solnet.Serum/MarketManager.cs +++ b/Solnet.Serum/MarketManager.cs @@ -211,7 +211,7 @@ private async Task GetOpenOrdersAccountAsync() new MemCmp { Offset = 45, Bytes = _ownerAccount } }; RequestResult> accounts = await - _serumClient.RpcClient.GetProgramAccountsAsync(SerumProgram.ProgramIdKey, + _serumClient.RpcClient.GetProgramAccountsAsync(SerumProgram.MainNetProgramIdKeyV3, dataSize: OpenOrdersAccount.Layout.SpanLength, memCmpList: filters); if (!accounts.WasRequestSuccessfullyHandled) return; @@ -298,8 +298,8 @@ public async Task SubscribeTradesAsync(Action, ulong> action) { List tradeEvents = (from evt in queue.Events - where evt.Flags.IsFill && evt.NativeQuantityPaid > 0 - select MarketUtils.ProcessTradeEvent(evt, _baseDecimals, _quoteDecimals)).ToList(); + where evt.Flags.IsFill && evt.NativeQuantityPaid > 0 + select MarketUtils.ProcessTradeEvent(evt, _baseDecimals, _quoteDecimals)).ToList(); action(tradeEvents, slot); }, Market.EventQueue, Commitment.Confirmed); } @@ -396,14 +396,31 @@ public async Task NewOrderAsync(Order order) order.ConvertOrderValues(_baseDecimals, _quoteDecimals, Market); txBuilder.AddInstruction(SerumProgram.NewOrderV3( - Market, + _marketAccount, ooa, + Market.RequestQueue, + Market.EventQueue, + Market.Bids, + Market.Asks, order.Side == Side.Buy ? qAta : bAta, _ownerAccount, - order, + Market.BaseVault, + Market.QuoteVault, + TokenProgram.ProgramIdKey, + SysVars.RentKey, + SerumProgram.MainNetProgramIdKeyV3, + order.Side, + order.RawPrice, + order.RawQuantity, + order.Type, + order.ClientOrderId, + order.SelfTradeBehavior, + ushort.MaxValue, + order.MaxQuoteQuantity, _srmAccount)); txBuilder.AddInstruction(SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, ooa, _ownerAccount, @@ -471,14 +488,31 @@ public async Task NewOrderAsync( PublicKey ooa = await GetOrCreateOpenOrdersAccount(txBuilder); txBuilder.AddInstruction(SerumProgram.NewOrderV3( - Market, + _marketAccount, ooa, + Market.RequestQueue, + Market.EventQueue, + Market.Bids, + Market.Asks, order.Side == Side.Buy ? qAta : bAta, _ownerAccount, - order, + Market.BaseVault, + Market.QuoteVault, + TokenProgram.ProgramIdKey, + SysVars.RentKey, + SerumProgram.MainNetProgramIdKeyV3, + order.Side, + order.RawPrice, + order.RawQuantity, + order.Type, + order.ClientOrderId, + order.SelfTradeBehavior, + ushort.MaxValue, + order.MaxQuoteQuantity, _srmAccount)); txBuilder.AddInstruction(SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, ooa, _ownerAccount, @@ -540,12 +574,17 @@ public async Task CancelOrderAsync(BigInteger orderId) (PublicKey qAta, bool qWrapped) = GetOrCreateQuoteTokenAccountAndWrapSolIfNeeded(txBuilder, isCancelOrder: true); txBuilder.AddInstruction(SerumProgram.CancelOrderV2( - Market, + SerumProgram.MainNetProgramIdKeyV3, + _marketAccount, + Market.Bids, + Market.Asks, _openOrdersAccount, _ownerAccount, + Market.EventQueue, openOrder.IsBid ? Side.Buy : Side.Sell, openOrder.OrderId)) .AddInstruction(SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, _openOrdersAccount, _ownerAccount, @@ -599,10 +638,16 @@ public async Task CancelOrderAsync(ulong clientId) (PublicKey qAta, bool qWrapped) = GetOrCreateQuoteTokenAccountAndWrapSolIfNeeded(txBuilder, isCancelOrder: true); txBuilder.AddInstruction(SerumProgram.CancelOrderByClientIdV2( - Market, + SerumProgram.MainNetProgramIdKeyV3, + _marketAccount, + Market.Bids, + Market.Asks, _openOrdersAccount, - _ownerAccount, clientId)) + _ownerAccount, + Market.EventQueue, + clientId)) .AddInstruction(SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, _openOrdersAccount, _ownerAccount, @@ -660,6 +705,7 @@ public async Task> CancelAllOrdersAsync() (PublicKey qAta, bool qWrapped) = GetOrCreateQuoteTokenAccountAndWrapSolIfNeeded(txBuilder, isCancelOrder: true); TransactionInstruction settleIx = SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, _openOrdersAccount, _ownerAccount, @@ -672,9 +718,13 @@ public async Task> CancelAllOrdersAsync() TransactionInstruction txInstruction = SerumProgram.CancelOrderV2( - Market, + SerumProgram.MainNetProgramIdKeyV3, + _marketAccount, + Market.Bids, + Market.Asks, _openOrdersAccount, _ownerAccount, + Market.EventQueue, OpenOrders[i].IsBid ? Side.Buy : Side.Sell, OpenOrders[i].OrderId); @@ -747,6 +797,7 @@ public async Task SettleFundsAsync(PublicKey referrer = n (PublicKey qAta, bool qWrapped) = GetOrCreateQuoteTokenAccountAndWrapSolIfNeeded(txBuilder, isCancelOrder: true); txBuilder.AddInstruction(SerumProgram.SettleFunds( + SerumProgram.MainNetProgramIdKeyV3, Market, _openOrdersAccount, _ownerAccount, @@ -927,9 +978,10 @@ await _serumClient.RpcClient.GetMinimumBalanceForRentExemptionAsync(OpenOrdersAc account, lamports.Result, OpenOrdersAccount.Layout.SpanLength, - SerumProgram.ProgramIdKey); + SerumProgram.MainNetProgramIdKeyV3); txBuilder.AddInstruction(txInstruction); txInstruction = SerumProgram.InitOpenOrders( + SerumProgram.MainNetProgramIdKeyV3, account, _ownerAccount, _marketAccount); diff --git a/Solnet.Serum/SerumProgram.cs b/Solnet.Serum/SerumProgram.cs index f7bac74..be78a2d 100644 --- a/Solnet.Serum/SerumProgram.cs +++ b/Solnet.Serum/SerumProgram.cs @@ -1,5 +1,7 @@ using Solnet.Programs; +using Solnet.Programs.Abstract; using Solnet.Programs.Utilities; +using Solnet.Rpc; using Solnet.Rpc.Models; using Solnet.Rpc.Utilities; using Solnet.Serum.Models; @@ -18,12 +20,17 @@ namespace Solnet.Serum /// https://github.com/project-serum/serum-dex/blob/master/dex/src/instruction.rs /// /// - public class SerumProgram + public class SerumProgram : BaseProgram { /// - /// The Serum V3 Program key. + /// The Serum V3 Program key for . /// - public static readonly PublicKey ProgramIdKey = new("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"); + public static readonly PublicKey MainNetProgramIdKeyV3 = new("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"); + + /// + /// The Serum V3 Program key for . + /// + public static readonly PublicKey DevNetProgramIdKeyV3 = new ("DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY"); /// /// The public key of the Serum token mint. @@ -48,7 +55,26 @@ public class SerumProgram /// /// The program's name. /// - private const string ProgramName = "Serum Program"; + private const string DefaultProgramName = "Serum Program"; + + /// + /// Initialize the with the given program id key. + /// + /// The program id key. + /// The program name. + public SerumProgram(PublicKey programIdKey, string programName) : base(programIdKey, programName) {} + + /// + /// Initialize the for . + /// + /// The instance. + public static SerumProgram CreateDevNet() => new SerumProgram(DevNetProgramIdKeyV3, DefaultProgramName); + + /// + /// Initialize the for . + /// + /// The instance. + public static SerumProgram CreateMainNet() => new SerumProgram(DevNetProgramIdKeyV3, DefaultProgramName); /// /// Initializes an instruction to create a new Order on Serum v3. @@ -60,7 +86,7 @@ public class SerumProgram /// The to place. /// The public key of the SRM wallet for fee discount. /// The transaction instruction. - public static TransactionInstruction NewOrderV3(Market market, PublicKey openOrdersAccount, + public TransactionInstruction NewOrderV3(Market market, PublicKey openOrdersAccount, PublicKey orderPayer, PublicKey openOrdersAccountOwner, Order order, PublicKey serumFeeDiscount = null) => NewOrderV3(market.OwnAddress, openOrdersAccount, market.RequestQueue, market.EventQueue, market.Bids, market.Asks, orderPayer, openOrdersAccountOwner, market.BaseVault, market.QuoteVault, @@ -141,7 +167,22 @@ public static TransactionInstruction NewOrderV3( /// The of the quote wallet or token account. /// The of the quote wallet or token account. /// The transaction instruction. - public static TransactionInstruction SettleFunds(Market market, PublicKey openOrdersAccount, PublicKey owner, + public TransactionInstruction SettleFunds(Market market, PublicKey openOrdersAccount, PublicKey owner, + PublicKey baseWallet, PublicKey quoteWallet, PublicKey referrerPcWallet = null) + => SettleFunds(ProgramIdKey, market, openOrdersAccount, owner, baseWallet, quoteWallet, referrerPcWallet); + + /// + /// Initializes an instruction to settle funds on Serum. + /// + /// The of the Serum Program associated with this market. + /// The market we are trading on. + /// The of the associated with this and . + /// The of the account that owns the payer and the open orders account. + /// The of the coin wallet or token account. + /// The of the quote wallet or token account. + /// The of the quote wallet or token account. + /// The transaction instruction. + public static TransactionInstruction SettleFunds(PublicKey programId, Market market, PublicKey openOrdersAccount, PublicKey owner, PublicKey baseWallet, PublicKey quoteWallet, PublicKey referrerPcWallet = null) { byte[] vaultSignerAddress = SerumProgramData.DeriveVaultSignerAddress(market); @@ -167,7 +208,7 @@ public static TransactionInstruction SettleFunds(Market market, PublicKey openOr return new TransactionInstruction { - ProgramId = ProgramIdKey, Keys = keys, Data = SerumProgramData.EncodeSettleFundsData() + ProgramId = programId, Keys = keys, Data = SerumProgramData.EncodeSettleFundsData() }; } @@ -180,13 +221,14 @@ public static TransactionInstruction SettleFunds(Market market, PublicKey openOr /// The of the price coin account. /// The maximum number of events to consume. /// The transaction instruction. - public static TransactionInstruction ConsumeEvents(List openOrdersAccounts, + public TransactionInstruction ConsumeEvents(List openOrdersAccounts, Market market, PublicKey coinAccount, PublicKey pcAccount, ushort limit) - => ConsumeEvents(openOrdersAccounts, market.OwnAddress, market.EventQueue, coinAccount, pcAccount, limit); + => ConsumeEvents(ProgramIdKey, openOrdersAccounts, market.OwnAddress, market.EventQueue, coinAccount, pcAccount, limit); /// /// Initializes an instruction to consume events of a list of open orders accounts in a given market on Serum. /// + /// The of the Serum Program associated with this market. /// A list of of the associated with this and . /// The of the we are consuming events on. /// The of the 's event queue. @@ -194,7 +236,7 @@ public static TransactionInstruction ConsumeEvents(List openOrdersAcc /// The of the price coin account. /// The maximum number of events to consume. /// The transaction instruction. - public static TransactionInstruction ConsumeEvents(List openOrdersAccounts, + public static TransactionInstruction ConsumeEvents(PublicKey programId, List openOrdersAccounts, PublicKey market, PublicKey eventQueue, PublicKey coinAccount, PublicKey pcAccount, ushort limit) { List keys = new(); @@ -206,7 +248,7 @@ public static TransactionInstruction ConsumeEvents(List openOrdersAcc return new TransactionInstruction { - ProgramId = ProgramIdKey, Keys = keys, Data = SerumProgramData.EncodeConsumeEventsData(limit) + ProgramId = programId, Keys = keys, Data = SerumProgramData.EncodeConsumeEventsData(limit) }; } @@ -219,7 +261,7 @@ public static TransactionInstruction ConsumeEvents(List openOrdersAcc /// The side of the order. /// The order's id, fetched from a . /// The transaction instruction. - public static TransactionInstruction CancelOrderV2( + public TransactionInstruction CancelOrderV2( Market market, PublicKey openOrdersAccount, PublicKey openOrdersAccountOwner, Side side, BigInteger orderId) => CancelOrderV2(ProgramIdKey, market.OwnAddress, market.Bids, market.Asks, openOrdersAccount, openOrdersAccountOwner, market.EventQueue, side, orderId); @@ -265,7 +307,7 @@ public static TransactionInstruction CancelOrderV2(PublicKey programId, PublicKe /// The of the that owns the . /// The client's orderId /// The transaction instruction. - public static TransactionInstruction CancelOrderByClientIdV2(Market market, PublicKey openOrdersAccount, + public TransactionInstruction CancelOrderByClientIdV2(Market market, PublicKey openOrdersAccount, PublicKey openOrdersAccountOwner, ulong clientOrderId) => CancelOrderByClientIdV2(ProgramIdKey, market.OwnAddress, market.Bids, market.Asks, openOrdersAccount, openOrdersAccountOwner, market.EventQueue, clientOrderId); @@ -312,7 +354,7 @@ public static TransactionInstruction CancelOrderByClientIdV2(PublicKey programId /// The of the destination account. /// The of the market. /// The transaction instruction. - public static TransactionInstruction CloseOpenOrders(PublicKey openOrdersAccount, + public TransactionInstruction CloseOpenOrders(PublicKey openOrdersAccount, PublicKey openOrdersAccountOwner, PublicKey destination, PublicKey market) => CloseOpenOrders(ProgramIdKey, openOrdersAccount, openOrdersAccountOwner, destination, market); @@ -353,7 +395,7 @@ public static TransactionInstruction CloseOpenOrders(PublicKey programId, Public /// The of the market. /// The of the market authority. /// The transaction instruction. - public static TransactionInstruction InitOpenOrders(PublicKey openOrdersAccount, + public TransactionInstruction InitOpenOrders(PublicKey openOrdersAccount, PublicKey openOrdersAccountOwner, PublicKey market, PublicKey marketAuthority = null) => InitOpenOrders(ProgramIdKey, openOrdersAccount, openOrdersAccountOwner, market, marketAuthority); @@ -396,7 +438,7 @@ public static TransactionInstruction InitOpenOrders(PublicKey programId, PublicK /// The of the . /// The of the owner. /// The transaction instruction. - public static TransactionInstruction Prune(Market market, PublicKey pruneAuthority, PublicKey openOrdersAccount, + public TransactionInstruction Prune(Market market, PublicKey pruneAuthority, PublicKey openOrdersAccount, PublicKey openOrdersAccountOwner) => Prune(ProgramIdKey, market.OwnAddress, market.Bids, market.Asks, pruneAuthority, openOrdersAccount, openOrdersAccountOwner, market.EventQueue, ushort.MaxValue); @@ -452,9 +494,9 @@ public static DecodedInstruction Decode(ReadOnlySpan data, IList(), InnerInstructions = new List() }; diff --git a/Solnet.Serum/SerumProgramData.cs b/Solnet.Serum/SerumProgramData.cs index 3346448..94dbcfe 100644 --- a/Solnet.Serum/SerumProgramData.cs +++ b/Solnet.Serum/SerumProgramData.cs @@ -312,8 +312,9 @@ internal static void DecodeNewOrderV3(DecodedInstruction decodedInstruction, Rea /// /// The market. /// The vault's signer nonce. + /// The program id key. /// The vault signer address. - public static byte[] DeriveVaultSignerAddress(PublicKey market, ulong vaultSignerNonce) + public static byte[] DeriveVaultSignerAddress(PublicKey market, ulong vaultSignerNonce, PublicKey programIdKey) { byte[] buffer = new byte[8]; buffer.WriteU64(vaultSignerNonce, 0); @@ -321,7 +322,7 @@ public static byte[] DeriveVaultSignerAddress(PublicKey market, ulong vaultSigne List seeds = new() { market.KeyBytes, BitConverter.GetBytes(vaultSignerNonce) }; bool success = AddressExtensions.TryCreateProgramAddress(seeds, - SerumProgram.ProgramIdKey.KeyBytes, out byte[] vaultSignerAddress); + programIdKey, out byte[] vaultSignerAddress); return !success ? null : vaultSignerAddress; } @@ -330,8 +331,23 @@ public static byte[] DeriveVaultSignerAddress(PublicKey market, ulong vaultSigne /// Derive the vault signer address for the given market. /// /// The market. + /// The program id key. /// The vault signer address. /// Throws exception when unable to derive the vault signer address. - public static byte[] DeriveVaultSignerAddress(Market market) => DeriveVaultSignerAddress(market.OwnAddress, market.VaultSignerNonce); + public static byte[] DeriveVaultSignerAddress(Market market, PublicKey programIdKey) + => DeriveVaultSignerAddress(market.OwnAddress, market.VaultSignerNonce, programIdKey); + + /// + /// Derive the vault signer address for the given market. + /// + /// + /// This method defaults to using as the program id key. + /// If you wish to derive the vault signer address using a different program id use . + /// + /// The market. + /// The vault signer address. + /// Throws exception when unable to derive the vault signer address. + public static byte[] DeriveVaultSignerAddress(Market market) + => DeriveVaultSignerAddress(market.OwnAddress, market.VaultSignerNonce, SerumProgram.MainNetProgramIdKeyV3); } } \ No newline at end of file