sememe 0.0.0-stage → 0.4.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2777 -2
  3. package/bin/sememe.mjs +556 -0
  4. package/index.mjs +48 -0
  5. package/interface/ata-ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL.json +62 -0
  6. package/interface/native-11111111111111111111111111111111.json +226 -0
  7. package/interface/native-ComputeBudget111111111111111111111111111111.json +72 -0
  8. package/interface/raydium-675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8.json +352 -0
  9. package/interface/token-TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA.json +334 -0
  10. package/interface/token-TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb.json +535 -0
  11. package/interface/token-metadata.json +132 -0
  12. package/package.json +71 -4
  13. package/src/account-list.mjs +308 -0
  14. package/src/account-union.mjs +523 -0
  15. package/src/account.mjs +199 -0
  16. package/src/acquire.mjs +145 -0
  17. package/src/adopt.mjs +206 -0
  18. package/src/ata-interface.mjs +276 -0
  19. package/src/ata.mjs +223 -0
  20. package/src/base58.mjs +96 -0
  21. package/src/canonical.mjs +24 -0
  22. package/src/cli-surface.mjs +300 -0
  23. package/src/codec.mjs +1118 -0
  24. package/src/conformance.mjs +431 -0
  25. package/src/corpus/harvest-compute-budget-2026-10-31.json +19122 -0
  26. package/src/corpus/harvest-system-2026-10-31.json +26090 -0
  27. package/src/decode.mjs +286 -0
  28. package/src/dialect.mjs +180 -0
  29. package/src/discriminators.mjs +192 -0
  30. package/src/drift.mjs +172 -0
  31. package/src/gap.mjs +205 -0
  32. package/src/lighthouse.mjs +168 -0
  33. package/src/lock.mjs +440 -0
  34. package/src/native-audit.mjs +56 -0
  35. package/src/native-corpus.mjs +57 -0
  36. package/src/native-interface.mjs +252 -0
  37. package/src/native.mjs +324 -0
  38. package/src/peer.mjs +95 -0
  39. package/src/program-id.mjs +74 -0
  40. package/src/pull.mjs +117 -0
  41. package/src/rawle.mjs +454 -0
  42. package/src/raydium-interface.mjs +747 -0
  43. package/src/raydium.mjs +391 -0
  44. package/src/receipt-digest.mjs +84 -0
  45. package/src/receipt-name.mjs +128 -0
  46. package/src/receipt-order.mjs +56 -0
  47. package/src/shank.mjs +73 -0
  48. package/src/short-forms.mjs +209 -0
  49. package/src/store-read.mjs +253 -0
  50. package/src/store-write.mjs +46 -0
  51. package/src/token-interface.mjs +394 -0
  52. package/src/token-metadata-interface.mjs +371 -0
  53. package/src/token-metadata.mjs +317 -0
  54. package/src/token.mjs +443 -0
  55. package/src/union.mjs +428 -0
  56. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/LICENSE.txt +201 -0
  57. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/compute-budget-interface/src/lib.rs +93 -0
  58. package/vendor/anza-solana-sdk/8db406e2edfafa25939ec782b77b5b6f30de164d/system-interface/src/instruction.rs +1899 -0
  59. package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/LICENSE +21 -0
  60. package/vendor/lighthouse/4c579479c98635e419b1b167f08be02a71604a71/lighthouse.json +2769 -0
  61. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/LICENSE +201 -0
  62. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/instruction.rs +1189 -0
  63. package/vendor/raydium-amm/91739d8d9f5cf347e0ce14ebe4d2bb7069fb31b6/program/src/state.rs +1348 -0
  64. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/LICENSE +201 -0
  65. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/instruction.rs +169 -0
  66. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/interface/src/lib.rs +12 -0
  67. package/vendor/spl-associated-token-account/fbf5379e7398ac8b231c73ee8a9ff677b43dd0ec/program/src/processor.rs +308 -0
  68. package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/LICENSE.txt +176 -0
  69. package/vendor/spl-token/737788ff5bcc3f1f44cfb222f25483187650be76/interface/src/instruction.rs +1963 -0
  70. package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/LICENSE.txt +176 -0
  71. package/vendor/spl-token-2022/5251dcc07ecbcb721d6c4f0231090defadf00311/interface/src/instruction.rs +2868 -0
  72. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/LICENSE +201 -0
  73. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/error.rs +58 -0
  74. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/instruction.rs +596 -0
  75. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/lib.rs +21 -0
  76. package/vendor/spl-token-metadata-interface/7038969ec74a89f1afdb9bc97c112d4d26fead9a/interface/src/state.rs +229 -0
@@ -0,0 +1,1189 @@
1
+ //! Instruction types
2
+
3
+ #![allow(clippy::too_many_arguments)]
4
+ #![allow(deprecated)]
5
+
6
+ use crate::state::{AmmParams, Fees};
7
+ use arrayref::array_ref;
8
+ use solana_program::{
9
+ instruction::{AccountMeta, Instruction},
10
+ program_error::ProgramError,
11
+ program_pack::Pack,
12
+ pubkey::Pubkey,
13
+ sysvar,
14
+ };
15
+ use std::convert::TryInto;
16
+ use std::mem::size_of;
17
+
18
+ #[repr(C)]
19
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
20
+ pub struct InitializeInstruction {
21
+ /// nonce used to create valid program address
22
+ pub nonce: u8,
23
+ /// utc timestamps for pool open
24
+ pub open_time: u64,
25
+ }
26
+
27
+ #[repr(C)]
28
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
29
+ pub struct InitializeInstruction2 {
30
+ /// nonce used to create valid program address
31
+ pub nonce: u8,
32
+ /// utc timestamps for pool open
33
+ pub open_time: u64,
34
+ /// init token pc amount
35
+ pub init_pc_amount: u64,
36
+ /// init token coin amount
37
+ pub init_coin_amount: u64,
38
+ }
39
+
40
+ #[repr(C)]
41
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
42
+ pub struct PreInitializeInstruction {
43
+ /// nonce used to create valid program address
44
+ pub nonce: u8,
45
+ }
46
+
47
+ #[repr(C)]
48
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
49
+ pub struct MonitorStepInstruction {
50
+ /// max value of plan/new/cancel orders
51
+ pub plan_order_limit: u16,
52
+ pub place_order_limit: u16,
53
+ pub cancel_order_limit: u16,
54
+ }
55
+
56
+ #[repr(C)]
57
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
58
+ pub struct DepositInstruction {
59
+ /// Pool token amount to transfer. token_a and token_b amount are set by
60
+ /// the current exchange rate and size of the pool
61
+ pub max_coin_amount: u64,
62
+ pub max_pc_amount: u64,
63
+ pub base_side: u64,
64
+ pub other_amount_min: Option<u64>,
65
+ }
66
+
67
+ #[repr(C)]
68
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
69
+ pub struct WithdrawInstruction {
70
+ /// Pool token amount to transfer. token_a and token_b amount are set by
71
+ /// the current exchange rate and size of the pool
72
+ pub amount: u64,
73
+ pub min_coin_amount: Option<u64>,
74
+ pub min_pc_amount: Option<u64>,
75
+ }
76
+
77
+ #[repr(C)]
78
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
79
+ pub struct SetParamsInstruction {
80
+ pub param: u8,
81
+ pub value: Option<u64>,
82
+ pub fees: Option<Fees>,
83
+ }
84
+
85
+ #[repr(C)]
86
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
87
+ pub struct WithdrawSrmInstruction {
88
+ pub amount: u64,
89
+ }
90
+
91
+ #[repr(C)]
92
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
93
+ pub struct SwapInstructionBaseIn {
94
+ // SOURCE amount to transfer, output to DESTINATION is based on the exchange rate
95
+ pub amount_in: u64,
96
+ /// Minimum amount of DESTINATION token to output, prevents excessive slippage
97
+ pub minimum_amount_out: u64,
98
+ }
99
+
100
+ #[repr(C)]
101
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
102
+ pub struct SwapInstructionBaseOut {
103
+ // SOURCE amount to transfer, output to DESTINATION is based on the exchange rate
104
+ pub max_amount_in: u64,
105
+ /// Minimum amount of DESTINATION token to output, prevents excessive slippage
106
+ pub amount_out: u64,
107
+ }
108
+
109
+ #[repr(C)]
110
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
111
+ pub struct SimulateInstruction {
112
+ pub param: u8,
113
+ pub swap_base_in_value: Option<SwapInstructionBaseIn>,
114
+ pub swap_base_out_value: Option<SwapInstructionBaseOut>,
115
+ }
116
+
117
+ #[repr(C)]
118
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
119
+ pub struct AdminCancelOrdersInstruction {
120
+ pub limit: u16,
121
+ }
122
+
123
+ /// Update config account params
124
+ #[repr(C)]
125
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]
126
+ pub struct ConfigArgs {
127
+ pub param: u8,
128
+ pub owner: Option<Pubkey>,
129
+ pub create_pool_fee: Option<u64>,
130
+ }
131
+
132
+ /// Instructions supported by the AmmInfo program.
133
+ #[repr(C)]
134
+ #[derive(Clone, Debug, PartialEq)]
135
+ pub enum AmmInstruction {
136
+ /// Initializes a new AmmInfo.
137
+ ///
138
+ /// Not supported yet, please use `Initialize2` to new a AMM pool
139
+ #[deprecated(note = "Not supported yet, please use `Initialize2` instead")]
140
+ Initialize(InitializeInstruction),
141
+
142
+ /// Initializes a new AMM pool.
143
+ ///
144
+ /// 0. `[]` Spl Token program id
145
+ /// 1. `[]` Associated Token program id
146
+ /// 2. `[]` Sys program id
147
+ /// 3. `[]` Rent program id
148
+ /// 4. `[writable]` New AMM Account to create.
149
+ /// 5. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
150
+ /// 6. `[writable]` AMM open orders Account
151
+ /// 7. `[writable]` AMM lp mint Account
152
+ /// 8. `[]` AMM coin mint Account
153
+ /// 9. `[]` AMM pc mint Account
154
+ /// 10. `[writable]` AMM coin vault Account. Must be non zero, owned by $authority.
155
+ /// 11. `[writable]` AMM pc vault Account. Must be non zero, owned by $authority.
156
+ /// 12. `[writable]` AMM target orders Account. To store plan orders informations.
157
+ /// 13. `[]` AMM config Account, derived from `find_program_address(&[&&AMM_CONFIG_SEED])`.
158
+ /// 14. `[]` AMM create pool fee destination Account
159
+ /// 15. `[]` Market program id
160
+ /// 16. `[writable]` Market Account. Market program is the owner.
161
+ /// 17. `[writable, signer]` User wallet Account
162
+ /// 18. `[]` User token coin Account
163
+ /// 19. '[]` User token pc Account
164
+ /// 20. `[writable]` User destination lp token ATA Account
165
+ Initialize2(InitializeInstruction2),
166
+
167
+ /// MonitorStep. To monitor place Amm order state machine turn around step by step.
168
+ #[deprecated(note = "Not supported yet")]
169
+ MonitorStep(MonitorStepInstruction),
170
+
171
+ /// Deposit some tokens into the pool. The output is a "pool" token representing ownership
172
+ /// into the pool. Inputs are converted to the current ratio.
173
+ ///
174
+ /// 0. `[]` Spl Token program id
175
+ /// 1. `[writable]` AMM Account
176
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
177
+ /// 3. `[]` AMM open_orders Account
178
+ /// 4. `[writable]` AMM target orders Account. To store plan orders infomations.
179
+ /// 5. `[writable]` AMM lp mint Account. Owned by $authority.
180
+ /// 6. `[writable]` AMM coin vault $authority can transfer amount,
181
+ /// 7. `[writable]` AMM pc vault $authority can transfer amount,
182
+ /// 8. `[]` Market Account. Market program is the owner.
183
+ /// 9. `[writable]` User coin token Account to deposit into.
184
+ /// 10. `[writable]` User pc token Account to deposit into.
185
+ /// 11. `[writable]` User lp token. To deposit the generated tokens, user is the owner.
186
+ /// 12. '[signer]` User wallet Account
187
+ /// 13. `[]` Market event queue Account.
188
+ Deposit(DepositInstruction),
189
+
190
+ /// Withdraw the vault tokens from the pool at the current ratio.
191
+ ///
192
+ /// 0. `[]` Spl Token program id
193
+ /// 1. `[writable]` AMM Account
194
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
195
+ /// 3. `[writable]` AMM open orders Account
196
+ /// 4. `[writable]` AMM target orders Account
197
+ /// 5. `[writable]` AMM lp mint Account. Owned by $authority.
198
+ /// 6. `[writable]` AMM coin vault Account to withdraw FROM,
199
+ /// 7. `[writable]` AMM pc vault Account to withdraw FROM,
200
+ /// 8. `[]` Market program id
201
+ /// 9. `[writable]` Market Account. Market program is the owner.
202
+ /// 10. `[writable]` Market coin vault Account
203
+ /// 11. `[writable]` Market pc vault Account
204
+ /// 12. '[]` Market vault signer Account
205
+ /// 13. `[writable]` User lp token Account.
206
+ /// 14. `[writable]` User token coin Account. user Account to credit.
207
+ /// 15. `[writable]` User token pc Account. user Account to credit.
208
+ /// 16. `[signer]` User wallet Account
209
+ /// 17. `[writable]` Market event queue Account
210
+ /// 18. `[writable]` Market bids Account
211
+ /// 19. `[writable]` Market asks Account
212
+ Withdraw(WithdrawInstruction),
213
+
214
+ /// Migrate the associated market from Serum to OpenBook.
215
+ #[deprecated(note = "Not supported yet")]
216
+ MigrateToOpenBook,
217
+
218
+ /// Set AMM params
219
+ ///
220
+ /// 0. `[writable]` AMM Account.
221
+ /// 1. `[signer]` Admin Account
222
+ SetParams(SetParamsInstruction),
223
+
224
+ /// Withdraw Pnl from pool by protocol
225
+ ///
226
+ /// 0. `[]` Spl Token program id
227
+ /// 1. `[writable]` AMM Account
228
+ /// 2. `[]` AMM config Account, derived from `find_program_address(&[&&AMM_CONFIG_SEED])`.
229
+ /// 3. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
230
+ /// 5. `[writable]` AMM coin vault account to withdraw FROM,
231
+ /// 6. `[writable]` AMM pc vault account to withdraw FROM,
232
+ /// 7. `[writable]` User coin token Account to withdraw to
233
+ /// 8. `[writable]` User pc token Account to withdraw to
234
+ /// 9. `[signer]` User wallet account
235
+ /// 10. `[writable]` AMM target orders Account
236
+ WithdrawPnl,
237
+
238
+ /// Withdraw (M)SRM from the (M)SRM Account used for fee discounts by admin
239
+ #[deprecated(note = "Not supported yet")]
240
+ WithdrawSrm(WithdrawSrmInstruction),
241
+
242
+ /// Swap coin or pc from pool, base amount_in with a slippage of minimum_amount_out
243
+ ///
244
+ /// 0. `[]` Spl Token program id
245
+ /// 1. `[writable]` AMM Account
246
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
247
+ /// 3. `[writable]` AMM open orders Account
248
+ /// 4. `[writable]` (optional)AMM target orders Account, no longer used in the contract, recommended no need to add this Account.
249
+ /// 5. `[writable]` AMM coin vault Account to swap FROM or To.
250
+ /// 6. `[writable]` AMM pc vault Account to swap FROM or To.
251
+ /// 7. `[]` Market program id
252
+ /// 8. `[writable]` Market Account. Market program is the owner.
253
+ /// 9. `[writable]` Market bids Account
254
+ /// 10. `[writable]` Market asks Account
255
+ /// 11. `[writable]` Market event queue Account
256
+ /// 12. `[writable]` Market coin vault Account
257
+ /// 13. `[writable]` Market pc vault Account
258
+ /// 14. '[]` Market vault signer Account
259
+ /// 15. `[writable]` User source token Account.
260
+ /// 16. `[writable]` User destination token Account.
261
+ /// 17. `[signer]` User wallet Account
262
+ SwapBaseIn(SwapInstructionBaseIn),
263
+
264
+ /// Continue Initializes a new Amm pool because of compute units limit.
265
+ /// Not supported yet, please use `Initialize2` to new a Amm pool
266
+ #[deprecated(note = "Not supported yet, please use `Initialize2` instead")]
267
+ PreInitialize(PreInitializeInstruction),
268
+
269
+ /// Swap coin or pc from pool, base amount_out with a slippage of max_amount_in
270
+ ///
271
+ /// 0. `[]` Spl Token program id
272
+ /// 1. `[writable]` AMM Account
273
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
274
+ /// 3. `[writable]` AMM open orders Account
275
+ /// 4. `[writable]` (optional)AMM target orders Account, no longer used in the contract, recommended no need to add this Account.
276
+ /// 5. `[writable]` AMM coin vault Account to swap FROM or To.
277
+ /// 6. `[writable]` AMM pc vault Account to swap FROM or To.
278
+ /// 7. `[]` Market program id
279
+ /// 8. `[writable]` Market Account. Market program is the owner.
280
+ /// 9. `[writable]` Market bids Account
281
+ /// 10. `[writable]` Market asks Account
282
+ /// 11. `[writable]` Market event queue Account
283
+ /// 12. `[writable]` Market coin vault Account
284
+ /// 13. `[writable]` Market pc vault Account
285
+ /// 14. '[]` Market vault signer Account
286
+ /// 15. `[writable]` User source token Account.
287
+ /// 16. `[writable]` User destination token Account.
288
+ /// 17. `[signer]` User wallet Account
289
+ SwapBaseOut(SwapInstructionBaseOut),
290
+
291
+ #[deprecated(note = "Not supported yet")]
292
+ SimulateInfo(SimulateInstruction),
293
+
294
+ #[deprecated(note = "Not supported yet")]
295
+ AdminCancelOrders(AdminCancelOrdersInstruction),
296
+
297
+ /// Create amm config account by admin
298
+ CreateConfigAccount,
299
+
300
+ /// Update amm config account by admin
301
+ UpdateConfigAccount(ConfigArgs),
302
+
303
+ /// Swap coin or pc from pool with orderbook disable, base amount_in with a slippage of minimum_amount_out
304
+ ///
305
+ /// 0. `[]` Spl Token program id
306
+ /// 1. `[writable]` AMM Account
307
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
308
+ /// 3. `[writable]` AMM coin vault Account to swap FROM or To.
309
+ /// 4. `[writable]` AMM pc vault Account to swap FROM or To.
310
+ /// 5. `[writable]` User source token Account.
311
+ /// 6. `[writable]` User destination token Account.
312
+ /// 7. `[signer]` User wallet Account
313
+ SwapBaseInV2(SwapInstructionBaseIn),
314
+
315
+ /// Swap coin or pc from pool with orderbook disable, base amount_out with a slippage of max_amount_in
316
+ ///
317
+ /// 0. `[]` Spl Token program id
318
+ /// 1. `[writable]` AMM Account
319
+ /// 2. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
320
+ /// 3. `[writable]` AMM coin vault Account to swap FROM or To.
321
+ /// 4. `[writable]` AMM pc vault Account to swap FROM or To.
322
+ /// 5. `[writable]` User source token Account.
323
+ /// 6. `[writable]` User destination token Account.
324
+ /// 7. `[signer]` User wallet Account
325
+ SwapBaseOutV2(SwapInstructionBaseOut),
326
+
327
+ /// Collect excess lamports, including accounts for SPL tokens owned by authority and Program PDA.
328
+ ///
329
+ /// 0. `[signer]` Collect lamports wallet
330
+ /// 1. `[]` $authority derived from `create_program_address(&[AUTHORITY_AMM, &[nonce]])`.
331
+ /// 2. `[]` Spl Token program id
332
+ /// 3. `..+M` `[writable]` M source lamports accounts.
333
+ WithdrawExcessLamports,
334
+ }
335
+
336
+ impl AmmInstruction {
337
+ /// Unpacks a byte buffer into a [AmmInstruction](enum.AmmInstruction.html).
338
+ pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
339
+ let (&tag, rest) = input
340
+ .split_first()
341
+ .ok_or(ProgramError::InvalidInstructionData)?;
342
+ Ok(match tag {
343
+ 1 => {
344
+ let (nonce, rest) = Self::unpack_u8(rest)?;
345
+ let (open_time, rest) = Self::unpack_u64(rest)?;
346
+ let (init_pc_amount, rest) = Self::unpack_u64(rest)?;
347
+ let (init_coin_amount, _reset) = Self::unpack_u64(rest)?;
348
+ Self::Initialize2(InitializeInstruction2 {
349
+ nonce,
350
+ open_time,
351
+ init_pc_amount,
352
+ init_coin_amount,
353
+ })
354
+ }
355
+ 3 => {
356
+ let (max_coin_amount, rest) = Self::unpack_u64(rest)?;
357
+ let (max_pc_amount, rest) = Self::unpack_u64(rest)?;
358
+ let (base_side, rest) = Self::unpack_u64(rest)?;
359
+ let other_amount_min = if rest.len() >= 8 {
360
+ let (other_amount_min, _rest) = Self::unpack_u64(rest)?;
361
+ Some(other_amount_min)
362
+ } else {
363
+ None
364
+ };
365
+ Self::Deposit(DepositInstruction {
366
+ max_coin_amount,
367
+ max_pc_amount,
368
+ base_side,
369
+ other_amount_min,
370
+ })
371
+ }
372
+ 4 => {
373
+ let (amount, rest) = Self::unpack_u64(rest)?;
374
+ let (min_coin_amount, min_pc_amount) = if rest.len() >= 16 {
375
+ let (min_coin_amount, rest) = Self::unpack_u64(rest)?;
376
+ let (min_pc_amount, _rest) = Self::unpack_u64(rest)?;
377
+ (Some(min_coin_amount), Some(min_pc_amount))
378
+ } else {
379
+ (None, None)
380
+ };
381
+ Self::Withdraw(WithdrawInstruction {
382
+ amount,
383
+ min_coin_amount,
384
+ min_pc_amount,
385
+ })
386
+ }
387
+ 6 => {
388
+ let (param, rest) = Self::unpack_u8(rest)?;
389
+ match AmmParams::from_u64(param as u64)? {
390
+ AmmParams::Fees => {
391
+ if rest.len() >= Fees::LEN {
392
+ let (fees, _rest) = rest.split_at(Fees::LEN);
393
+ let fees = Fees::unpack_from_slice(fees)?;
394
+ Self::SetParams(SetParamsInstruction {
395
+ param,
396
+ value: None,
397
+ fees: Some(fees),
398
+ })
399
+ } else {
400
+ return Err(ProgramError::InvalidInstructionData.into());
401
+ }
402
+ }
403
+ AmmParams::Status | AmmParams::State | AmmParams::SetOpenTime => {
404
+ if rest.len() >= 8 {
405
+ let (value, _rest) = Self::unpack_u64(rest)?;
406
+ Self::SetParams(SetParamsInstruction {
407
+ param,
408
+ value: Some(value),
409
+ fees: None,
410
+ })
411
+ } else {
412
+ return Err(ProgramError::InvalidInstructionData.into());
413
+ }
414
+ }
415
+ }
416
+ }
417
+ 7 => Self::WithdrawPnl,
418
+ 9 => {
419
+ let (amount_in, rest) = Self::unpack_u64(rest)?;
420
+ let (minimum_amount_out, _rest) = Self::unpack_u64(rest)?;
421
+ Self::SwapBaseIn(SwapInstructionBaseIn {
422
+ amount_in,
423
+ minimum_amount_out,
424
+ })
425
+ }
426
+ 11 => {
427
+ let (max_amount_in, rest) = Self::unpack_u64(rest)?;
428
+ let (amount_out, _rest) = Self::unpack_u64(rest)?;
429
+ Self::SwapBaseOut(SwapInstructionBaseOut {
430
+ max_amount_in,
431
+ amount_out,
432
+ })
433
+ }
434
+ 14 => Self::CreateConfigAccount,
435
+ 15 => {
436
+ let (param, rest) = Self::unpack_u8(rest)?;
437
+ match param {
438
+ 0 | 1 => {
439
+ if rest.len() >= 32 {
440
+ let pubkey = array_ref![rest, 0, 32];
441
+ Self::UpdateConfigAccount(ConfigArgs {
442
+ param,
443
+ owner: Some(Pubkey::new_from_array(*pubkey)),
444
+ create_pool_fee: None,
445
+ })
446
+ } else {
447
+ return Err(ProgramError::InvalidInstructionData.into());
448
+ }
449
+ }
450
+ 2 => {
451
+ let (create_pool_fee, _rest) = Self::unpack_u64(rest)?;
452
+ Self::UpdateConfigAccount(ConfigArgs {
453
+ param,
454
+ owner: None,
455
+ create_pool_fee: Some(create_pool_fee),
456
+ })
457
+ }
458
+ _ => {
459
+ return Err(ProgramError::InvalidInstructionData.into());
460
+ }
461
+ }
462
+ }
463
+ 16 => {
464
+ let (amount_in, rest) = Self::unpack_u64(rest)?;
465
+ let (minimum_amount_out, _rest) = Self::unpack_u64(rest)?;
466
+ Self::SwapBaseInV2(SwapInstructionBaseIn {
467
+ amount_in,
468
+ minimum_amount_out,
469
+ })
470
+ }
471
+ 17 => {
472
+ let (max_amount_in, rest) = Self::unpack_u64(rest)?;
473
+ let (amount_out, _rest) = Self::unpack_u64(rest)?;
474
+ Self::SwapBaseOutV2(SwapInstructionBaseOut {
475
+ max_amount_in,
476
+ amount_out,
477
+ })
478
+ }
479
+ 18 => Self::WithdrawExcessLamports,
480
+ 0 | 2 | 5 | 8 | 10 | 12 | 13 => {
481
+ // Not support instructions: 0, 2, 5, 8, 10, 12, 13.
482
+ unimplemented!("This instruction is not supported")
483
+ }
484
+ _ => {
485
+ return Err(ProgramError::InvalidInstructionData.into());
486
+ }
487
+ })
488
+ }
489
+
490
+ fn unpack_u8(input: &[u8]) -> Result<(u8, &[u8]), ProgramError> {
491
+ if input.len() >= 1 {
492
+ let (amount, rest) = input.split_at(1);
493
+ let amount = amount
494
+ .get(..1)
495
+ .and_then(|slice| slice.try_into().ok())
496
+ .map(u8::from_le_bytes)
497
+ .ok_or(ProgramError::InvalidInstructionData)?;
498
+ Ok((amount, rest))
499
+ } else {
500
+ Err(ProgramError::InvalidInstructionData.into())
501
+ }
502
+ }
503
+
504
+ fn unpack_u64(input: &[u8]) -> Result<(u64, &[u8]), ProgramError> {
505
+ if input.len() >= 8 {
506
+ let (amount, rest) = input.split_at(8);
507
+ let amount = amount
508
+ .get(..8)
509
+ .and_then(|slice| slice.try_into().ok())
510
+ .map(u64::from_le_bytes)
511
+ .ok_or(ProgramError::InvalidInstructionData)?;
512
+ Ok((amount, rest))
513
+ } else {
514
+ Err(ProgramError::InvalidInstructionData.into())
515
+ }
516
+ }
517
+
518
+ /// Packs a [AmmInstruction](enum.AmmInstruction.html) into a byte buffer.
519
+ pub fn pack(&self) -> Result<Vec<u8>, ProgramError> {
520
+ let mut buf = Vec::with_capacity(size_of::<Self>());
521
+ match &*self {
522
+ Self::Initialize2(InitializeInstruction2 {
523
+ nonce,
524
+ open_time,
525
+ init_pc_amount,
526
+ init_coin_amount,
527
+ }) => {
528
+ buf.push(1);
529
+ buf.push(*nonce);
530
+ buf.extend_from_slice(&open_time.to_le_bytes());
531
+ buf.extend_from_slice(&init_pc_amount.to_le_bytes());
532
+ buf.extend_from_slice(&init_coin_amount.to_le_bytes());
533
+ }
534
+ Self::Deposit(DepositInstruction {
535
+ max_coin_amount,
536
+ max_pc_amount,
537
+ base_side,
538
+ other_amount_min,
539
+ }) => {
540
+ buf.push(3);
541
+ buf.extend_from_slice(&max_coin_amount.to_le_bytes());
542
+ buf.extend_from_slice(&max_pc_amount.to_le_bytes());
543
+ buf.extend_from_slice(&base_side.to_le_bytes());
544
+ if other_amount_min.is_some() {
545
+ buf.extend_from_slice(&other_amount_min.unwrap().to_le_bytes());
546
+ }
547
+ }
548
+ Self::Withdraw(WithdrawInstruction {
549
+ amount,
550
+ min_coin_amount,
551
+ min_pc_amount,
552
+ }) => {
553
+ buf.push(4);
554
+ buf.extend_from_slice(&amount.to_le_bytes());
555
+ if min_coin_amount.is_some() && min_pc_amount.is_some() {
556
+ buf.extend_from_slice(&min_coin_amount.unwrap().to_le_bytes());
557
+ buf.extend_from_slice(&min_pc_amount.unwrap().to_le_bytes());
558
+ }
559
+ }
560
+ Self::SetParams(SetParamsInstruction { param, value, fees }) => {
561
+ buf.push(6);
562
+ buf.push(*param);
563
+ match AmmParams::from_u64(*param as u64).unwrap() {
564
+ AmmParams::Fees => {
565
+ let fees = match fees {
566
+ Some(a) => a,
567
+ None => return Err(ProgramError::InvalidInstructionData.into()),
568
+ };
569
+ let mut fees_slice = [0u8; Fees::LEN];
570
+ Pack::pack_into_slice(fees, &mut fees_slice[..]);
571
+ buf.extend_from_slice(&fees_slice);
572
+ }
573
+ _ => {
574
+ let value = match value {
575
+ Some(a) => a,
576
+ None => return Err(ProgramError::InvalidInstructionData.into()),
577
+ };
578
+ buf.extend_from_slice(&value.to_le_bytes());
579
+ }
580
+ }
581
+ }
582
+ Self::WithdrawPnl => {
583
+ buf.push(7);
584
+ }
585
+ Self::SwapBaseIn(SwapInstructionBaseIn {
586
+ amount_in,
587
+ minimum_amount_out,
588
+ }) => {
589
+ buf.push(9);
590
+ buf.extend_from_slice(&amount_in.to_le_bytes());
591
+ buf.extend_from_slice(&minimum_amount_out.to_le_bytes());
592
+ }
593
+ Self::SwapBaseOut(SwapInstructionBaseOut {
594
+ max_amount_in,
595
+ amount_out,
596
+ }) => {
597
+ buf.push(11);
598
+ buf.extend_from_slice(&max_amount_in.to_le_bytes());
599
+ buf.extend_from_slice(&amount_out.to_le_bytes());
600
+ }
601
+ Self::CreateConfigAccount => {
602
+ buf.push(14);
603
+ }
604
+ Self::UpdateConfigAccount(ConfigArgs {
605
+ param,
606
+ owner,
607
+ create_pool_fee,
608
+ }) => {
609
+ buf.push(15);
610
+ buf.push(*param);
611
+ match param {
612
+ 0 | 1 => {
613
+ let owner = match owner {
614
+ Some(owner) => {
615
+ if *owner == Pubkey::default() {
616
+ return Err(ProgramError::InvalidInstructionData.into());
617
+ } else {
618
+ owner
619
+ }
620
+ }
621
+ None => return Err(ProgramError::InvalidInstructionData.into()),
622
+ };
623
+ buf.extend_from_slice(&owner.to_bytes());
624
+ }
625
+ 2 => {
626
+ let create_pool_fee = match create_pool_fee {
627
+ Some(create_pool_fee) => create_pool_fee,
628
+ None => return Err(ProgramError::InvalidInstructionData.into()),
629
+ };
630
+ buf.extend_from_slice(&create_pool_fee.to_le_bytes());
631
+ }
632
+ _ => return Err(ProgramError::InvalidInstructionData.into()),
633
+ }
634
+ }
635
+ Self::SwapBaseInV2(SwapInstructionBaseIn {
636
+ amount_in,
637
+ minimum_amount_out,
638
+ }) => {
639
+ buf.push(16);
640
+ buf.extend_from_slice(&amount_in.to_le_bytes());
641
+ buf.extend_from_slice(&minimum_amount_out.to_le_bytes());
642
+ }
643
+ Self::SwapBaseOutV2(SwapInstructionBaseOut {
644
+ max_amount_in,
645
+ amount_out,
646
+ }) => {
647
+ buf.push(17);
648
+ buf.extend_from_slice(&max_amount_in.to_le_bytes());
649
+ buf.extend_from_slice(&amount_out.to_le_bytes());
650
+ }
651
+ Self::WithdrawExcessLamports => {
652
+ buf.push(18);
653
+ }
654
+ _ => {
655
+ // Not support instructions: 0, 2, 5, 8, 10, 12, 13, etc.
656
+ return Err(ProgramError::InvalidInstructionData.into());
657
+ }
658
+ }
659
+ Ok(buf)
660
+ }
661
+ }
662
+
663
+ /// Creates an 'initialize2' instruction.
664
+ pub fn initialize2(
665
+ amm_program: &Pubkey,
666
+ amm_pool: &Pubkey,
667
+ amm_authority: &Pubkey,
668
+ amm_open_orders: &Pubkey,
669
+ amm_lp_mint: &Pubkey,
670
+ amm_coin_mint: &Pubkey,
671
+ amm_pc_mint: &Pubkey,
672
+ amm_coin_vault: &Pubkey,
673
+ amm_pc_vault: &Pubkey,
674
+ amm_target_orders: &Pubkey,
675
+ amm_config: &Pubkey,
676
+ create_fee_destination: &Pubkey,
677
+ market_program: &Pubkey,
678
+ market: &Pubkey,
679
+ user_wallet: &Pubkey,
680
+ user_token_coin: &Pubkey,
681
+ user_token_pc: &Pubkey,
682
+ user_token_lp: &Pubkey,
683
+ nonce: u8,
684
+ open_time: u64,
685
+ init_pc_amount: u64,
686
+ init_coin_amount: u64,
687
+ ) -> Result<Instruction, ProgramError> {
688
+ let init_data = AmmInstruction::Initialize2(InitializeInstruction2 {
689
+ nonce,
690
+ open_time,
691
+ init_pc_amount,
692
+ init_coin_amount,
693
+ });
694
+ let data = init_data.pack()?;
695
+
696
+ let accounts = vec![
697
+ // spl & sys
698
+ AccountMeta::new_readonly(spl_token::id(), false),
699
+ AccountMeta::new_readonly(spl_associated_token_account::id(), false),
700
+ AccountMeta::new_readonly(solana_system_interface::program::id(), false),
701
+ AccountMeta::new_readonly(sysvar::rent::id(), false),
702
+ // amm
703
+ AccountMeta::new(*amm_pool, false),
704
+ AccountMeta::new_readonly(*amm_authority, false),
705
+ AccountMeta::new(*amm_open_orders, false),
706
+ AccountMeta::new(*amm_lp_mint, false),
707
+ AccountMeta::new_readonly(*amm_coin_mint, false),
708
+ AccountMeta::new_readonly(*amm_pc_mint, false),
709
+ AccountMeta::new(*amm_coin_vault, false),
710
+ AccountMeta::new(*amm_pc_vault, false),
711
+ AccountMeta::new(*amm_target_orders, false),
712
+ AccountMeta::new_readonly(*amm_config, false),
713
+ AccountMeta::new(*create_fee_destination, false),
714
+ // market
715
+ AccountMeta::new_readonly(*market_program, false),
716
+ AccountMeta::new_readonly(*market, false),
717
+ // user wallet
718
+ AccountMeta::new(*user_wallet, true),
719
+ AccountMeta::new(*user_token_coin, false),
720
+ AccountMeta::new(*user_token_pc, false),
721
+ AccountMeta::new(*user_token_lp, false),
722
+ ];
723
+
724
+ Ok(Instruction {
725
+ program_id: *amm_program,
726
+ accounts,
727
+ data,
728
+ })
729
+ }
730
+
731
+ /// Creates a 'deposit' instruction.
732
+ pub fn deposit(
733
+ amm_program: &Pubkey,
734
+ amm_pool: &Pubkey,
735
+ amm_authority: &Pubkey,
736
+ amm_open_orders: &Pubkey,
737
+ amm_target_orders: &Pubkey,
738
+ amm_lp_mint: &Pubkey,
739
+ amm_coin_vault: &Pubkey,
740
+ amm_pc_vault: &Pubkey,
741
+ market: &Pubkey,
742
+ market_event_queue: &Pubkey,
743
+ user_token_coin: &Pubkey,
744
+ user_token_pc: &Pubkey,
745
+ user_token_lp: &Pubkey,
746
+ user_owner: &Pubkey,
747
+ max_coin_amount: u64,
748
+ max_pc_amount: u64,
749
+ base_side: u64,
750
+ other_amount_min: Option<u64>,
751
+ ) -> Result<Instruction, ProgramError> {
752
+ let data = AmmInstruction::Deposit(DepositInstruction {
753
+ max_coin_amount,
754
+ max_pc_amount,
755
+ base_side,
756
+ other_amount_min,
757
+ })
758
+ .pack()?;
759
+
760
+ let accounts = vec![
761
+ // spl token
762
+ AccountMeta::new_readonly(spl_token::id(), false),
763
+ // amm
764
+ AccountMeta::new(*amm_pool, false),
765
+ AccountMeta::new_readonly(*amm_authority, false),
766
+ AccountMeta::new_readonly(*amm_open_orders, false),
767
+ AccountMeta::new(*amm_target_orders, false),
768
+ AccountMeta::new(*amm_lp_mint, false),
769
+ AccountMeta::new(*amm_coin_vault, false),
770
+ AccountMeta::new(*amm_pc_vault, false),
771
+ // market
772
+ AccountMeta::new_readonly(*market, false),
773
+ // user
774
+ AccountMeta::new(*user_token_coin, false),
775
+ AccountMeta::new(*user_token_pc, false),
776
+ AccountMeta::new(*user_token_lp, false),
777
+ AccountMeta::new_readonly(*user_owner, true),
778
+ AccountMeta::new_readonly(*market_event_queue, false),
779
+ ];
780
+
781
+ Ok(Instruction {
782
+ program_id: *amm_program,
783
+ accounts,
784
+ data,
785
+ })
786
+ }
787
+
788
+ /// Creates a 'withdraw' instruction.
789
+ pub fn withdraw(
790
+ amm_program: &Pubkey,
791
+ amm_pool: &Pubkey,
792
+ amm_authority: &Pubkey,
793
+ amm_open_orders: &Pubkey,
794
+ amm_target_orders: &Pubkey,
795
+ amm_lp_mint: &Pubkey,
796
+ amm_coin_vault: &Pubkey,
797
+ amm_pc_vault: &Pubkey,
798
+ market_program: &Pubkey,
799
+ market: &Pubkey,
800
+ market_coin_vault: &Pubkey,
801
+ market_pc_vault: &Pubkey,
802
+ market_vault_signer: &Pubkey,
803
+ user_token_lp: &Pubkey,
804
+ user_token_coin: &Pubkey,
805
+ user_token_pc: &Pubkey,
806
+ user_owner: &Pubkey,
807
+ market_event_queue: &Pubkey,
808
+ market_bids: &Pubkey,
809
+ market_asks: &Pubkey,
810
+
811
+ referrer_pc_account: Option<&Pubkey>,
812
+
813
+ amount: u64,
814
+ min_coin_amount: Option<u64>,
815
+ min_pc_amount: Option<u64>,
816
+ ) -> Result<Instruction, ProgramError> {
817
+ let data = AmmInstruction::Withdraw(WithdrawInstruction {
818
+ amount,
819
+ min_coin_amount,
820
+ min_pc_amount,
821
+ })
822
+ .pack()?;
823
+
824
+ let mut accounts = vec![
825
+ // spl token
826
+ AccountMeta::new_readonly(spl_token::id(), false),
827
+ // amm
828
+ AccountMeta::new(*amm_pool, false),
829
+ AccountMeta::new_readonly(*amm_authority, false),
830
+ AccountMeta::new(*amm_open_orders, false),
831
+ AccountMeta::new(*amm_target_orders, false),
832
+ AccountMeta::new(*amm_lp_mint, false),
833
+ AccountMeta::new(*amm_coin_vault, false),
834
+ AccountMeta::new(*amm_pc_vault, false),
835
+ // market
836
+ AccountMeta::new_readonly(*market_program, false),
837
+ AccountMeta::new(*market, false),
838
+ AccountMeta::new(*market_coin_vault, false),
839
+ AccountMeta::new(*market_pc_vault, false),
840
+ AccountMeta::new_readonly(*market_vault_signer, false),
841
+ // user
842
+ AccountMeta::new(*user_token_lp, false),
843
+ AccountMeta::new(*user_token_coin, false),
844
+ AccountMeta::new(*user_token_pc, false),
845
+ AccountMeta::new_readonly(*user_owner, true),
846
+ AccountMeta::new(*market_event_queue, false),
847
+ AccountMeta::new(*market_bids, false),
848
+ AccountMeta::new(*market_asks, false),
849
+ ];
850
+
851
+ if let Some(referrer_pc_key) = referrer_pc_account {
852
+ accounts.push(AccountMeta::new(*referrer_pc_key, false));
853
+ }
854
+
855
+ Ok(Instruction {
856
+ program_id: *amm_program,
857
+ accounts,
858
+ data,
859
+ })
860
+ }
861
+
862
+ /// Creates a 'swap base in' instruction.
863
+ pub fn swap_base_in(
864
+ amm_program: &Pubkey,
865
+ amm_pool: &Pubkey,
866
+ amm_authority: &Pubkey,
867
+ amm_open_orders: &Pubkey,
868
+ amm_coin_vault: &Pubkey,
869
+ amm_pc_vault: &Pubkey,
870
+ market_program: &Pubkey,
871
+ market: &Pubkey,
872
+ market_bids: &Pubkey,
873
+ market_asks: &Pubkey,
874
+ market_event_queue: &Pubkey,
875
+ market_coin_vault: &Pubkey,
876
+ market_pc_vault: &Pubkey,
877
+ market_vault_signer: &Pubkey,
878
+ user_token_source: &Pubkey,
879
+ user_token_destination: &Pubkey,
880
+ user_source_owner: &Pubkey,
881
+
882
+ amount_in: u64,
883
+ minimum_amount_out: u64,
884
+ ) -> Result<Instruction, ProgramError> {
885
+ let data = AmmInstruction::SwapBaseIn(SwapInstructionBaseIn {
886
+ amount_in,
887
+ minimum_amount_out,
888
+ })
889
+ .pack()?;
890
+
891
+ let accounts = vec![
892
+ // spl token
893
+ AccountMeta::new_readonly(spl_token::id(), false),
894
+ // amm
895
+ AccountMeta::new(*amm_pool, false),
896
+ AccountMeta::new_readonly(*amm_authority, false),
897
+ AccountMeta::new(*amm_open_orders, false),
898
+ // AccountMeta::new(*amm_target_orders, false),
899
+ AccountMeta::new(*amm_coin_vault, false),
900
+ AccountMeta::new(*amm_pc_vault, false),
901
+ // market
902
+ AccountMeta::new_readonly(*market_program, false),
903
+ AccountMeta::new(*market, false),
904
+ AccountMeta::new(*market_bids, false),
905
+ AccountMeta::new(*market_asks, false),
906
+ AccountMeta::new(*market_event_queue, false),
907
+ AccountMeta::new(*market_coin_vault, false),
908
+ AccountMeta::new(*market_pc_vault, false),
909
+ AccountMeta::new_readonly(*market_vault_signer, false),
910
+ // user
911
+ AccountMeta::new(*user_token_source, false),
912
+ AccountMeta::new(*user_token_destination, false),
913
+ AccountMeta::new_readonly(*user_source_owner, true),
914
+ ];
915
+
916
+ Ok(Instruction {
917
+ program_id: *amm_program,
918
+ accounts,
919
+ data,
920
+ })
921
+ }
922
+
923
+ /// Creates a 'swap base in v2' instruction.
924
+ pub fn swap_base_in_v2(
925
+ amm_program: &Pubkey,
926
+ amm_pool: &Pubkey,
927
+ amm_authority: &Pubkey,
928
+ amm_coin_vault: &Pubkey,
929
+ amm_pc_vault: &Pubkey,
930
+ user_token_source: &Pubkey,
931
+ user_token_destination: &Pubkey,
932
+ user_source_owner: &Pubkey,
933
+
934
+ amount_in: u64,
935
+ minimum_amount_out: u64,
936
+ ) -> Result<Instruction, ProgramError> {
937
+ let data = AmmInstruction::SwapBaseInV2(SwapInstructionBaseIn {
938
+ amount_in,
939
+ minimum_amount_out,
940
+ })
941
+ .pack()?;
942
+
943
+ let accounts = vec![
944
+ // spl token
945
+ AccountMeta::new_readonly(spl_token::id(), false),
946
+ // amm
947
+ AccountMeta::new(*amm_pool, false),
948
+ AccountMeta::new_readonly(*amm_authority, false),
949
+ AccountMeta::new(*amm_coin_vault, false),
950
+ AccountMeta::new(*amm_pc_vault, false),
951
+ // user
952
+ AccountMeta::new(*user_token_source, false),
953
+ AccountMeta::new(*user_token_destination, false),
954
+ AccountMeta::new_readonly(*user_source_owner, true),
955
+ ];
956
+
957
+ Ok(Instruction {
958
+ program_id: *amm_program,
959
+ accounts,
960
+ data,
961
+ })
962
+ }
963
+
964
+ /// Creates a 'swap base out' instruction.
965
+ pub fn swap_base_out(
966
+ amm_program: &Pubkey,
967
+ amm_pool: &Pubkey,
968
+ amm_authority: &Pubkey,
969
+ amm_open_orders: &Pubkey,
970
+ amm_coin_vault: &Pubkey,
971
+ amm_pc_vault: &Pubkey,
972
+ market_program: &Pubkey,
973
+ market: &Pubkey,
974
+ market_bids: &Pubkey,
975
+ market_asks: &Pubkey,
976
+ market_event_queue: &Pubkey,
977
+ market_coin_vault: &Pubkey,
978
+ market_pc_vault: &Pubkey,
979
+ market_vault_signer: &Pubkey,
980
+ user_token_source: &Pubkey,
981
+ user_token_destination: &Pubkey,
982
+ user_source_owner: &Pubkey,
983
+
984
+ max_amount_in: u64,
985
+ amount_out: u64,
986
+ ) -> Result<Instruction, ProgramError> {
987
+ let data = AmmInstruction::SwapBaseOut(SwapInstructionBaseOut {
988
+ max_amount_in,
989
+ amount_out,
990
+ })
991
+ .pack()?;
992
+
993
+ let accounts = vec![
994
+ // spl token
995
+ AccountMeta::new_readonly(spl_token::id(), false),
996
+ // amm
997
+ AccountMeta::new(*amm_pool, false),
998
+ AccountMeta::new_readonly(*amm_authority, false),
999
+ AccountMeta::new(*amm_open_orders, false),
1000
+ // AccountMeta::new(*amm_target_orders, false),
1001
+ AccountMeta::new(*amm_coin_vault, false),
1002
+ AccountMeta::new(*amm_pc_vault, false),
1003
+ // market
1004
+ AccountMeta::new_readonly(*market_program, false),
1005
+ AccountMeta::new(*market, false),
1006
+ AccountMeta::new(*market_bids, false),
1007
+ AccountMeta::new(*market_asks, false),
1008
+ AccountMeta::new(*market_event_queue, false),
1009
+ AccountMeta::new(*market_coin_vault, false),
1010
+ AccountMeta::new(*market_pc_vault, false),
1011
+ AccountMeta::new_readonly(*market_vault_signer, false),
1012
+ // user
1013
+ AccountMeta::new(*user_token_source, false),
1014
+ AccountMeta::new(*user_token_destination, false),
1015
+ AccountMeta::new_readonly(*user_source_owner, true),
1016
+ ];
1017
+
1018
+ Ok(Instruction {
1019
+ program_id: *amm_program,
1020
+ accounts,
1021
+ data,
1022
+ })
1023
+ }
1024
+
1025
+ /// Creates a 'swap base out v2' instruction.
1026
+ pub fn swap_base_out_v2(
1027
+ amm_program: &Pubkey,
1028
+ amm_pool: &Pubkey,
1029
+ amm_authority: &Pubkey,
1030
+ amm_coin_vault: &Pubkey,
1031
+ amm_pc_vault: &Pubkey,
1032
+ user_token_source: &Pubkey,
1033
+ user_token_destination: &Pubkey,
1034
+ user_source_owner: &Pubkey,
1035
+
1036
+ max_amount_in: u64,
1037
+ amount_out: u64,
1038
+ ) -> Result<Instruction, ProgramError> {
1039
+ let data = AmmInstruction::SwapBaseOutV2(SwapInstructionBaseOut {
1040
+ max_amount_in,
1041
+ amount_out,
1042
+ })
1043
+ .pack()?;
1044
+
1045
+ let accounts = vec![
1046
+ // spl token
1047
+ AccountMeta::new_readonly(spl_token::id(), false),
1048
+ // amm
1049
+ AccountMeta::new(*amm_pool, false),
1050
+ AccountMeta::new_readonly(*amm_authority, false),
1051
+ AccountMeta::new(*amm_coin_vault, false),
1052
+ AccountMeta::new(*amm_pc_vault, false),
1053
+ // user
1054
+ AccountMeta::new(*user_token_source, false),
1055
+ AccountMeta::new(*user_token_destination, false),
1056
+ AccountMeta::new_readonly(*user_source_owner, true),
1057
+ ];
1058
+
1059
+ Ok(Instruction {
1060
+ program_id: *amm_program,
1061
+ accounts,
1062
+ data,
1063
+ })
1064
+ }
1065
+
1066
+ /// Creates a 'withdrawpnl' instruction
1067
+ pub fn withdrawpnl(
1068
+ amm_program: &Pubkey,
1069
+ amm_pool: &Pubkey,
1070
+ amm_config: &Pubkey,
1071
+ amm_authority: &Pubkey,
1072
+ amm_coin_vault: &Pubkey,
1073
+ amm_pc_vault: &Pubkey,
1074
+ user_token_coin: &Pubkey,
1075
+ user_token_pc: &Pubkey,
1076
+ user_owner: &Pubkey,
1077
+ amm_target_orders: &Pubkey,
1078
+ ) -> Result<Instruction, ProgramError> {
1079
+ let data = AmmInstruction::WithdrawPnl.pack()?;
1080
+
1081
+ let accounts = vec![
1082
+ // spl token
1083
+ AccountMeta::new_readonly(spl_token::id(), false),
1084
+ // amm
1085
+ AccountMeta::new(*amm_pool, false),
1086
+ AccountMeta::new_readonly(*amm_config, false),
1087
+ AccountMeta::new_readonly(*amm_authority, false),
1088
+ AccountMeta::new(*amm_coin_vault, false),
1089
+ AccountMeta::new(*amm_pc_vault, false),
1090
+ AccountMeta::new(*user_token_coin, false),
1091
+ AccountMeta::new(*user_token_pc, false),
1092
+ AccountMeta::new_readonly(*user_owner, true),
1093
+ AccountMeta::new(*amm_target_orders, false),
1094
+ ];
1095
+
1096
+ Ok(Instruction {
1097
+ program_id: *amm_program,
1098
+ accounts,
1099
+ data,
1100
+ })
1101
+ }
1102
+
1103
+ /// Creates a 'SetParams' instruction.
1104
+ pub fn set_params(
1105
+ amm_program: &Pubkey,
1106
+ amm_pool: &Pubkey,
1107
+ admin: &Pubkey,
1108
+ param: u8,
1109
+ value: Option<u64>,
1110
+ fees: Option<Fees>,
1111
+ ) -> Result<Instruction, ProgramError> {
1112
+ let data = AmmInstruction::SetParams(SetParamsInstruction { param, value, fees }).pack()?;
1113
+
1114
+ let accounts = vec![
1115
+ // amm
1116
+ AccountMeta::new(*amm_pool, false),
1117
+ // admin
1118
+ AccountMeta::new_readonly(*admin, true),
1119
+ ];
1120
+ Ok(Instruction {
1121
+ program_id: *amm_program,
1122
+ accounts,
1123
+ data,
1124
+ })
1125
+ }
1126
+
1127
+ /// Creates an 'create_config_account' instruction.
1128
+ pub fn create_config_account(
1129
+ amm_program: &Pubkey,
1130
+ admin: &Pubkey,
1131
+ amm_config: &Pubkey,
1132
+ pnl_owner: &Pubkey,
1133
+ ) -> Result<Instruction, ProgramError> {
1134
+ let data = AmmInstruction::CreateConfigAccount.pack()?;
1135
+ let accounts = vec![
1136
+ AccountMeta::new(*admin, true),
1137
+ AccountMeta::new(*amm_config, false),
1138
+ AccountMeta::new_readonly(*pnl_owner, false),
1139
+ AccountMeta::new_readonly(solana_system_interface::program::id(), false),
1140
+ ];
1141
+ Ok(Instruction {
1142
+ program_id: *amm_program,
1143
+ accounts,
1144
+ data,
1145
+ })
1146
+ }
1147
+
1148
+ /// Creates an 'update_config_account' instruction.
1149
+ pub fn update_config_account(
1150
+ amm_program: &Pubkey,
1151
+ admin: &Pubkey,
1152
+ amm_config: &Pubkey,
1153
+ config_args: ConfigArgs,
1154
+ ) -> Result<Instruction, ProgramError> {
1155
+ let data = AmmInstruction::UpdateConfigAccount(config_args).pack()?;
1156
+ let accounts = vec![
1157
+ AccountMeta::new_readonly(*admin, true),
1158
+ AccountMeta::new(*amm_config, false),
1159
+ ];
1160
+ Ok(Instruction {
1161
+ program_id: *amm_program,
1162
+ accounts,
1163
+ data,
1164
+ })
1165
+ }
1166
+
1167
+ /// Creates an 'withdraw_excess_lamports' instruction.
1168
+ pub fn withdraw_excess_lamports(
1169
+ amm_program: &Pubkey,
1170
+ collect_lamports: &Pubkey,
1171
+ amm_authority: &Pubkey,
1172
+ source_lamports_pubkeys: &[&Pubkey],
1173
+ ) -> Result<Instruction, ProgramError> {
1174
+ let data = AmmInstruction::WithdrawExcessLamports.pack()?;
1175
+ let mut accounts = vec![
1176
+ AccountMeta::new(*collect_lamports, true),
1177
+ AccountMeta::new_readonly(*amm_authority, false),
1178
+ AccountMeta::new_readonly(solana_system_interface::program::id(), false),
1179
+ ];
1180
+
1181
+ for source_pubkey in source_lamports_pubkeys.iter() {
1182
+ accounts.push(AccountMeta::new(**source_pubkey, false));
1183
+ }
1184
+ Ok(Instruction {
1185
+ program_id: *amm_program,
1186
+ accounts,
1187
+ data,
1188
+ })
1189
+ }