@picon-finance/dlmm-sdk 1.2.0 → 1.3.0

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 (221) hide show
  1. package/README.md +107 -16
  2. package/dist/entities/admin_config.d.ts +23 -0
  3. package/dist/entities/admin_config.d.ts.map +1 -0
  4. package/dist/entities/admin_config.js +54 -0
  5. package/dist/entities/bin_array.d.ts +36 -0
  6. package/dist/entities/bin_array.d.ts.map +1 -0
  7. package/dist/entities/bin_array.js +62 -0
  8. package/dist/entities/dlmm_program.d.ts +50 -0
  9. package/dist/entities/dlmm_program.d.ts.map +1 -0
  10. package/dist/entities/dlmm_program.js +73 -0
  11. package/dist/entities/index.d.ts +7 -0
  12. package/dist/entities/index.d.ts.map +1 -0
  13. package/dist/entities/index.js +6 -0
  14. package/dist/entities/pool.d.ts +71 -0
  15. package/dist/entities/pool.d.ts.map +1 -0
  16. package/dist/entities/pool.js +189 -0
  17. package/dist/entities/position.d.ts +51 -0
  18. package/dist/entities/position.d.ts.map +1 -0
  19. package/dist/entities/position.js +248 -0
  20. package/dist/entities/position_pool.d.ts +7 -0
  21. package/dist/entities/position_pool.d.ts.map +1 -0
  22. package/dist/entities/position_pool.js +30 -0
  23. package/dist/entities/types.d.ts +5 -0
  24. package/dist/entities/types.d.ts.map +1 -0
  25. package/dist/entities/types.js +0 -0
  26. package/dist/events.d.ts +9 -1
  27. package/dist/events.d.ts.map +1 -1
  28. package/dist/events.js +48 -0
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/program_addresses.d.ts.map +1 -1
  33. package/dist/program_addresses.js +0 -5
  34. package/dist/utils/assert.d.ts +9 -0
  35. package/dist/utils/assert.d.ts.map +1 -0
  36. package/dist/utils/assert.js +10 -0
  37. package/dist/utils/bin_location.d.ts +4 -0
  38. package/dist/utils/bin_location.d.ts.map +1 -1
  39. package/dist/utils/bin_location.js +0 -12
  40. package/dist/utils/chunk.d.ts +1 -0
  41. package/dist/utils/chunk.d.ts.map +1 -1
  42. package/dist/utils/chunk.js +4 -0
  43. package/dist/utils/type_guards.d.ts +2 -0
  44. package/dist/utils/type_guards.d.ts.map +1 -1
  45. package/dist/utils/type_guards.js +7 -0
  46. package/package.json +1 -2
  47. package/src/entities/admin_config.ts +122 -0
  48. package/src/entities/bin_array.ts +156 -0
  49. package/src/entities/dlmm_program.ts +210 -0
  50. package/src/entities/index.ts +6 -0
  51. package/src/entities/pool.ts +392 -0
  52. package/src/entities/position.ts +444 -0
  53. package/src/entities/position_pool.ts +68 -0
  54. package/src/entities/types.ts +3 -0
  55. package/src/events.ts +77 -0
  56. package/src/index.ts +2 -1
  57. package/src/program_addresses.ts +0 -6
  58. package/src/utils/assert.ts +25 -0
  59. package/src/utils/bin_location.ts +5 -12
  60. package/src/utils/chunk.ts +9 -0
  61. package/src/utils/type_guards.ts +12 -0
  62. package/dist/actions/accept_admin_authority.d.ts +0 -13
  63. package/dist/actions/accept_admin_authority.d.ts.map +0 -1
  64. package/dist/actions/accept_admin_authority.js +0 -7
  65. package/dist/actions/claim_fee.d.ts +0 -21
  66. package/dist/actions/claim_fee.d.ts.map +0 -1
  67. package/dist/actions/claim_fee.js +0 -40
  68. package/dist/actions/claim_multiple_fees.d.ts +0 -19
  69. package/dist/actions/claim_multiple_fees.d.ts.map +0 -1
  70. package/dist/actions/claim_multiple_fees.js +0 -81
  71. package/dist/actions/claim_protocol_fee.d.ts +0 -18
  72. package/dist/actions/claim_protocol_fee.d.ts.map +0 -1
  73. package/dist/actions/claim_protocol_fee.js +0 -33
  74. package/dist/actions/close_position.d.ts +0 -14
  75. package/dist/actions/close_position.d.ts.map +0 -1
  76. package/dist/actions/close_position.js +0 -14
  77. package/dist/actions/create_admin_config.d.ts +0 -15
  78. package/dist/actions/create_admin_config.d.ts.map +0 -1
  79. package/dist/actions/create_admin_config.js +0 -30
  80. package/dist/actions/create_bin_array.d.ts +0 -16
  81. package/dist/actions/create_bin_array.d.ts.map +0 -1
  82. package/dist/actions/create_bin_array.js +0 -10
  83. package/dist/actions/create_pool.d.ts +0 -21
  84. package/dist/actions/create_pool.d.ts.map +0 -1
  85. package/dist/actions/create_pool.js +0 -22
  86. package/dist/actions/delete_bin_array.d.ts +0 -16
  87. package/dist/actions/delete_bin_array.d.ts.map +0 -1
  88. package/dist/actions/delete_bin_array.js +0 -13
  89. package/dist/actions/deposit_by_weight.d.ts +0 -27
  90. package/dist/actions/deposit_by_weight.d.ts.map +0 -1
  91. package/dist/actions/deposit_by_weight.js +0 -52
  92. package/dist/actions/get_admin_config.d.ts +0 -4
  93. package/dist/actions/get_admin_config.d.ts.map +0 -1
  94. package/dist/actions/get_admin_config.js +0 -7
  95. package/dist/actions/get_bin_arrays_by_indices.d.ts +0 -5
  96. package/dist/actions/get_bin_arrays_by_indices.d.ts.map +0 -1
  97. package/dist/actions/get_bin_arrays_by_indices.js +0 -6
  98. package/dist/actions/get_pool.d.ts +0 -4
  99. package/dist/actions/get_pool.d.ts.map +0 -1
  100. package/dist/actions/get_pool.js +0 -5
  101. package/dist/actions/get_position.d.ts +0 -4
  102. package/dist/actions/get_position.d.ts.map +0 -1
  103. package/dist/actions/get_position.js +0 -5
  104. package/dist/actions/get_position_by_position_mint.d.ts +0 -4
  105. package/dist/actions/get_position_by_position_mint.d.ts.map +0 -1
  106. package/dist/actions/get_position_by_position_mint.js +0 -6
  107. package/dist/actions/get_positions_by_owner.d.ts +0 -5
  108. package/dist/actions/get_positions_by_owner.d.ts.map +0 -1
  109. package/dist/actions/get_positions_by_owner.js +0 -33
  110. package/dist/actions/get_positions_by_position_mints.d.ts +0 -5
  111. package/dist/actions/get_positions_by_position_mints.d.ts.map +0 -1
  112. package/dist/actions/get_positions_by_position_mints.js +0 -9
  113. package/dist/actions/helpers/build_swap_transaction_message.d.ts +0 -22
  114. package/dist/actions/helpers/build_swap_transaction_message.d.ts.map +0 -1
  115. package/dist/actions/helpers/build_swap_transaction_message.js +0 -50
  116. package/dist/actions/helpers/build_transaction_message.d.ts +0 -20
  117. package/dist/actions/helpers/build_transaction_message.d.ts.map +0 -1
  118. package/dist/actions/helpers/build_transaction_message.js +0 -5
  119. package/dist/actions/helpers/index.d.ts +0 -8
  120. package/dist/actions/helpers/index.d.ts.map +0 -1
  121. package/dist/actions/helpers/index.js +0 -7
  122. package/dist/actions/helpers/resolve_active_bin_and_mints.d.ts +0 -12
  123. package/dist/actions/helpers/resolve_active_bin_and_mints.d.ts.map +0 -1
  124. package/dist/actions/helpers/resolve_active_bin_and_mints.js +0 -13
  125. package/dist/actions/helpers/resolve_admin_config_address.d.ts +0 -3
  126. package/dist/actions/helpers/resolve_admin_config_address.d.ts.map +0 -1
  127. package/dist/actions/helpers/resolve_admin_config_address.js +0 -9
  128. package/dist/actions/helpers/resolve_mint_info.d.ts +0 -10
  129. package/dist/actions/helpers/resolve_mint_info.d.ts.map +0 -1
  130. package/dist/actions/helpers/resolve_mint_info.js +0 -20
  131. package/dist/actions/helpers/resolve_position_range.d.ts +0 -12
  132. package/dist/actions/helpers/resolve_position_range.d.ts.map +0 -1
  133. package/dist/actions/helpers/resolve_position_range.js +0 -12
  134. package/dist/actions/helpers/resolve_token_mints_and_programs.d.ts +0 -15
  135. package/dist/actions/helpers/resolve_token_mints_and_programs.d.ts.map +0 -1
  136. package/dist/actions/helpers/resolve_token_mints_and_programs.js +0 -29
  137. package/dist/actions/index.d.ts +0 -31
  138. package/dist/actions/index.d.ts.map +0 -1
  139. package/dist/actions/index.js +0 -28
  140. package/dist/actions/is_admin_config_active.d.ts +0 -4
  141. package/dist/actions/is_admin_config_active.d.ts.map +0 -1
  142. package/dist/actions/is_admin_config_active.js +0 -7
  143. package/dist/actions/on_event.d.ts +0 -11
  144. package/dist/actions/on_event.d.ts.map +0 -1
  145. package/dist/actions/on_event.js +0 -50
  146. package/dist/actions/open_position.d.ts +0 -17
  147. package/dist/actions/open_position.d.ts.map +0 -1
  148. package/dist/actions/open_position.js +0 -31
  149. package/dist/actions/quote.d.ts +0 -13
  150. package/dist/actions/quote.d.ts.map +0 -1
  151. package/dist/actions/quote.js +0 -43
  152. package/dist/actions/set_metadata_update_authority.d.ts +0 -14
  153. package/dist/actions/set_metadata_update_authority.d.ts.map +0 -1
  154. package/dist/actions/set_metadata_update_authority.js +0 -7
  155. package/dist/actions/set_pool_dynamic_fee_config.d.ts +0 -16
  156. package/dist/actions/set_pool_dynamic_fee_config.d.ts.map +0 -1
  157. package/dist/actions/set_pool_dynamic_fee_config.js +0 -7
  158. package/dist/actions/set_pool_protocol_share.d.ts +0 -15
  159. package/dist/actions/set_pool_protocol_share.d.ts.map +0 -1
  160. package/dist/actions/set_pool_protocol_share.js +0 -7
  161. package/dist/actions/swap.d.ts +0 -22
  162. package/dist/actions/swap.d.ts.map +0 -1
  163. package/dist/actions/swap.js +0 -19
  164. package/dist/actions/sync_pool.d.ts +0 -15
  165. package/dist/actions/sync_pool.d.ts.map +0 -1
  166. package/dist/actions/sync_pool.js +0 -26
  167. package/dist/actions/transfer_admin_authority.d.ts +0 -14
  168. package/dist/actions/transfer_admin_authority.d.ts.map +0 -1
  169. package/dist/actions/transfer_admin_authority.js +0 -7
  170. package/dist/actions/withdraw.d.ts +0 -22
  171. package/dist/actions/withdraw.d.ts.map +0 -1
  172. package/dist/actions/withdraw.js +0 -41
  173. package/dist/utils/admin_config.d.ts +0 -3
  174. package/dist/utils/admin_config.d.ts.map +0 -1
  175. package/dist/utils/admin_config.js +0 -4
  176. package/dist/utils/bin_array.d.ts +0 -8
  177. package/dist/utils/bin_array.d.ts.map +0 -1
  178. package/dist/utils/bin_array.js +0 -29
  179. package/dist/utils/compute_budget.d.ts +0 -11
  180. package/dist/utils/compute_budget.d.ts.map +0 -1
  181. package/dist/utils/compute_budget.js +0 -22
  182. package/src/actions/accept_admin_authority.ts +0 -17
  183. package/src/actions/claim_fee.ts +0 -84
  184. package/src/actions/claim_multiple_fees.ts +0 -123
  185. package/src/actions/claim_protocol_fee.ts +0 -68
  186. package/src/actions/close_position.ts +0 -21
  187. package/src/actions/create_admin_config.ts +0 -51
  188. package/src/actions/create_bin_array.ts +0 -30
  189. package/src/actions/create_pool.ts +0 -49
  190. package/src/actions/delete_bin_array.ts +0 -33
  191. package/src/actions/deposit_by_weight.ts +0 -107
  192. package/src/actions/get_admin_config.ts +0 -13
  193. package/src/actions/get_bin_arrays_by_indices.ts +0 -15
  194. package/src/actions/get_pool.ts +0 -8
  195. package/src/actions/get_position.ts +0 -8
  196. package/src/actions/get_position_by_position_mint.ts +0 -14
  197. package/src/actions/get_positions_by_owner.ts +0 -48
  198. package/src/actions/get_positions_by_position_mints.ts +0 -21
  199. package/src/actions/helpers/build_swap_transaction_message.ts +0 -86
  200. package/src/actions/helpers/build_transaction_message.ts +0 -45
  201. package/src/actions/helpers/index.ts +0 -7
  202. package/src/actions/helpers/resolve_active_bin_and_mints.ts +0 -21
  203. package/src/actions/helpers/resolve_admin_config_address.ts +0 -11
  204. package/src/actions/helpers/resolve_mint_info.ts +0 -36
  205. package/src/actions/helpers/resolve_position_range.ts +0 -21
  206. package/src/actions/helpers/resolve_token_mints_and_programs.ts +0 -56
  207. package/src/actions/index.ts +0 -34
  208. package/src/actions/is_admin_config_active.ts +0 -14
  209. package/src/actions/on_event.ts +0 -78
  210. package/src/actions/open_position.ts +0 -66
  211. package/src/actions/quote.ts +0 -70
  212. package/src/actions/set_metadata_update_authority.ts +0 -17
  213. package/src/actions/set_pool_dynamic_fee_config.ts +0 -17
  214. package/src/actions/set_pool_protocol_share.ts +0 -17
  215. package/src/actions/swap.ts +0 -56
  216. package/src/actions/sync_pool.ts +0 -35
  217. package/src/actions/transfer_admin_authority.ts +0 -17
  218. package/src/actions/withdraw.ts +0 -87
  219. package/src/utils/admin_config.ts +0 -6
  220. package/src/utils/bin_array.ts +0 -45
  221. package/src/utils/compute_budget.ts +0 -58
@@ -0,0 +1,210 @@
1
+ import {
2
+ createSolanaRpc,
3
+ parseBase64RpcAccount,
4
+ type Address,
5
+ type Account,
6
+ type Instruction,
7
+ type AccountInfoBase,
8
+ type TransactionSigner,
9
+ type FetchAccountConfig,
10
+ type FetchAccountsConfig,
11
+ type AccountInfoWithPubkey,
12
+ type AccountInfoWithBase64EncodedData,
13
+ } from "@solana/kit";
14
+ import {
15
+ getTokenDecoder,
16
+ TOKEN_2022_PROGRAM_ADDRESS,
17
+ } from "@solana-program/token-2022";
18
+
19
+ import { MAINNET_PROGRAM_ADDRESS } from "../program_addresses";
20
+ import type { QuoteOutput } from "../quote";
21
+ import {
22
+ Pool,
23
+ createPool,
24
+ } from "./pool";
25
+ import { findAllPositionAddresses } from "./position";
26
+ import { fetchAllMaybePositionPoolsChunked } from "./position_pool";
27
+ import {
28
+ getAdminConfig,
29
+ createAdminConfig,
30
+ isAdminConfigActive,
31
+ acceptAdminAuthority,
32
+ transferAdminAuthority,
33
+ setMetadataUpdateAuthority,
34
+ } from "./admin_config";
35
+ import { generated } from "..";
36
+
37
+ export class DlmmProgram {
38
+ #rpc: ReturnType<typeof createSolanaRpc>;
39
+ #programAddress: Address;
40
+
41
+ public constructor(
42
+ rpc: ReturnType<typeof createSolanaRpc>,
43
+ programAddress: Address = MAINNET_PROGRAM_ADDRESS,
44
+ ) {
45
+ this.#rpc = rpc;
46
+ this.#programAddress = programAddress;
47
+ }
48
+
49
+ public get rpc() { return this.#rpc; }
50
+ public get programAddress() { return this.#programAddress; }
51
+
52
+ public async getPool(
53
+ address: Address,
54
+ config?: FetchAccountConfig,
55
+ ): Promise<Pool> {
56
+ return await Pool.load(this.#rpc, address, this.#programAddress, config);
57
+ }
58
+
59
+ public async createPool(
60
+ authority: TransactionSigner,
61
+ params: {
62
+ binStep: number,
63
+ feeRate: number,
64
+ protocolShare: number,
65
+ activeBinId: number,
66
+ tokenMintX: Address,
67
+ tokenMintY: Address,
68
+ tokenProgramX: Address,
69
+ tokenProgramY: Address,
70
+ },
71
+ ): Promise<Instruction> {
72
+ return await createPool(
73
+ { authority, ...params },
74
+ { programAddress: this.#programAddress },
75
+ );
76
+ }
77
+
78
+ public async swap(
79
+ user: TransactionSigner,
80
+ poolAddress: Address,
81
+ params: { xToY: boolean, amountIn: bigint, minAmountOut: bigint },
82
+ config?: FetchAccountConfig,
83
+ ): Promise<Instruction[]> {
84
+ const pool = await this.getPool(poolAddress, config);
85
+ return await pool.swap(user, params);
86
+ }
87
+
88
+ public async quote(
89
+ poolAddress: Address,
90
+ params: { xToY: boolean, amountIn: bigint, slippageToleranceBps: number },
91
+ config?: FetchAccountConfig,
92
+ ): Promise<QuoteOutput> {
93
+ const pool = await this.getPool(poolAddress, config);
94
+ return await pool.quote(params);
95
+ }
96
+
97
+ public async quoteAndSwap(
98
+ user: TransactionSigner,
99
+ poolAddress: Address,
100
+ params: { xToY: boolean, amountIn: bigint, slippageToleranceBps: number },
101
+ config?: FetchAccountConfig,
102
+ ): Promise<{ quoteOutput: QuoteOutput, instructions: Instruction[] }> {
103
+ const pool = await this.getPool(poolAddress, config);
104
+ return await pool.quoteAndSwap(user, params);
105
+ }
106
+
107
+ public async getAllPositionMintsByOwner(
108
+ owner: Address,
109
+ config?: FetchAccountsConfig,
110
+ ): Promise<Map<Address, Address[]>> {
111
+ const { commitment, minContextSlot, abortSignal } = config ?? {};
112
+ const { value: tokenAccounts } = await this.#rpc
113
+ .getTokenAccountsByOwner(
114
+ owner,
115
+ { programId: TOKEN_2022_PROGRAM_ADDRESS },
116
+ { commitment, minContextSlot, encoding: "base64" },
117
+ )
118
+ .send({ abortSignal });
119
+ const candidateMints = decodeCandidatePositionMints(tokenAccounts);
120
+ if (candidateMints.length === 0) {
121
+ return new Map();
122
+ }
123
+
124
+ const positionAddresses = await findAllPositionAddresses(
125
+ { positionMints: candidateMints },
126
+ { programAddress: this.#programAddress },
127
+ );
128
+ const maybePools = await fetchAllMaybePositionPoolsChunked(
129
+ this.#rpc,
130
+ positionAddresses,
131
+ config,
132
+ );
133
+
134
+ return new Map(
135
+ Map.groupBy(
136
+ maybePools.flatMap((maybePool, i) =>
137
+ maybePool ? [{ pool: maybePool.pool, mint: candidateMints[i] }] : []),
138
+ ({ pool }) => pool,
139
+ ).entries().map(([pool, pairs]) => [pool, pairs.map(({ mint }) => mint)]),
140
+ );
141
+ }
142
+
143
+ public async createAdminConfig(
144
+ deployer: TransactionSigner,
145
+ params: { authority: Address, metadataUpdateAuthority?: Address },
146
+ ): Promise<Instruction> {
147
+ return await createAdminConfig(
148
+ { deployer, ...params },
149
+ { programAddress: this.#programAddress },
150
+ );
151
+ }
152
+
153
+ public async transferAdminAuthority(
154
+ authority: TransactionSigner,
155
+ newAuthority: Address,
156
+ ): Promise<Instruction> {
157
+ return await transferAdminAuthority(
158
+ { authority, newAuthority },
159
+ { programAddress: this.#programAddress },
160
+ );
161
+ }
162
+
163
+ public async acceptAdminAuthority(
164
+ pendingAuthority: TransactionSigner,
165
+ ): Promise<Instruction> {
166
+ return await acceptAdminAuthority(
167
+ { pendingAuthority },
168
+ { programAddress: this.#programAddress },
169
+ );
170
+ }
171
+
172
+ public async setMetadataUpdateAuthority(
173
+ authority: TransactionSigner,
174
+ metadataUpdateAuthority: Address,
175
+ ): Promise<Instruction> {
176
+ return await setMetadataUpdateAuthority(
177
+ { authority, metadataUpdateAuthority },
178
+ { programAddress: this.#programAddress },
179
+ );
180
+ }
181
+
182
+ public async getAdminConfig(
183
+ config?: FetchAccountConfig,
184
+ ): Promise<Account<generated.AdminConfig>> {
185
+ return await getAdminConfig(
186
+ this.#rpc,
187
+ { programAddress: this.#programAddress, ...config },
188
+ );
189
+ }
190
+
191
+ public async isAdminConfigActive(
192
+ config?: FetchAccountConfig,
193
+ ): Promise<boolean> {
194
+ return await isAdminConfigActive(
195
+ this.#rpc,
196
+ { programAddress: this.#programAddress, ...config },
197
+ );
198
+ }
199
+ }
200
+
201
+ const tokenDecoder = getTokenDecoder();
202
+
203
+ function decodeCandidatePositionMints(
204
+ tokenAccounts: readonly AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase64EncodedData>[],
205
+ ): Address[] {
206
+ return tokenAccounts
207
+ .map(({ pubkey, account }) => tokenDecoder.decode(parseBase64RpcAccount(pubkey, account).data))
208
+ .filter(token => token.amount === 1n)
209
+ .map(token => token.mint);
210
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./admin_config";
2
+ export * from "./bin_array";
3
+ export * from "./dlmm_program";
4
+ export * from "./pool";
5
+ export * from "./position";
6
+ export * from "./types";
@@ -0,0 +1,392 @@
1
+ import {
2
+ createSolanaRpc,
3
+ AccountRole,
4
+ type Address,
5
+ type Account,
6
+ type Instruction,
7
+ type TransactionSigner,
8
+ type FetchAccountConfig,
9
+ type FetchAccountsConfig,
10
+ } from "@solana/kit";
11
+ import {
12
+ fetchAllMint,
13
+ type Mint,
14
+ } from "@solana-program/token-2022";
15
+
16
+ import { generated } from "..";
17
+ import { quote, type QuoteOutput } from "../quote";
18
+ import { isAccount } from "../utils/type_guards";
19
+ import { resolveAdminConfigAddress } from "./admin_config";
20
+ import { processAssociatedTokenAccountPair } from "../utils/ata";
21
+ import {
22
+ generateBinArrayIndicesForSwap,
23
+ generateBinArrayIndicesForSync,
24
+ } from "../utils/bin_location";
25
+ import { resolveTransferFee } from "../utils/transfer_fee";
26
+ import {
27
+ MAX_BIN_ARRAYS_PER_SWAP,
28
+ MAX_BIN_ARRAYS_PER_SYNC,
29
+ } from "../utils/constants";
30
+ import {
31
+ Position,
32
+ openPosition,
33
+ closePosition,
34
+ findPositionAddress,
35
+ findAllPositionAddresses,
36
+ } from "./position";
37
+ import { findAllBinArrayAddresses } from "./bin_array";
38
+ import { type ProgramConfig } from "./types";
39
+
40
+ export class Pool {
41
+ #programAddress: Address;
42
+ #rpc: ReturnType<typeof createSolanaRpc>;
43
+
44
+ #account: Account<generated.Pool>;
45
+ #mintX: Account<Mint>;
46
+ #mintY: Account<Mint>;
47
+
48
+ private constructor(
49
+ rpc: ReturnType<typeof createSolanaRpc>,
50
+ account: Account<generated.Pool>,
51
+ mintX: Account<Mint>,
52
+ mintY: Account<Mint>,
53
+ programAddress: Address,
54
+ ) {
55
+ this.#rpc = rpc;
56
+ this.#account = account;
57
+ this.#mintX = mintX;
58
+ this.#mintY = mintY;
59
+ this.#programAddress = programAddress;
60
+ }
61
+
62
+ public get rpc() { return this.#rpc; }
63
+
64
+ public get programAddress() { return this.#programAddress; }
65
+ public get address() { return this.#account.address; }
66
+ public get data() { return this.#account.data; }
67
+ public get activeBinId() { return this.data.activeBinId; }
68
+
69
+ public get tokenMintX() { return this.data.tokenMintX; }
70
+ public get tokenMintY() { return this.data.tokenMintY; }
71
+
72
+ public get tokenVaultX() { return this.data.tokenVaultX; }
73
+ public get tokenVaultY() { return this.data.tokenVaultY; }
74
+
75
+ public get tokenProgramX() { return this.#mintX.programAddress; }
76
+ public get tokenProgramY() { return this.#mintY.programAddress; }
77
+
78
+ public async refresh(data: Account<generated.Pool>): Promise<void>;
79
+ public async refresh(config?: FetchAccountConfig): Promise<void>;
80
+ public async refresh(arg?: Account<generated.Pool> | FetchAccountConfig) {
81
+ if (!isAccount<generated.Pool>(arg)) {
82
+ arg = await generated.fetchPool(this.#rpc, this.address, arg);
83
+ }
84
+ this.#account = arg;
85
+ }
86
+
87
+ public async getPosition(
88
+ address: Address,
89
+ config?: FetchAccountsConfig,
90
+ ): Promise<Position> {
91
+ return await Position.load(this, address, config);
92
+ }
93
+
94
+ public async getPositionByPositionMint(
95
+ positionMint: Address,
96
+ config?: FetchAccountsConfig,
97
+ ): Promise<Position> {
98
+ const address = await findPositionAddress(
99
+ { positionMint },
100
+ { programAddress: this.#programAddress },
101
+ );
102
+ return await Position.load(this, address, config);
103
+ }
104
+
105
+ public async getAllPositionsByPositionMints(
106
+ positionMints: Address[],
107
+ config?: FetchAccountsConfig,
108
+ ): Promise<Position[]> {
109
+ const addresses = await findAllPositionAddresses(
110
+ { positionMints },
111
+ { programAddress: this.#programAddress },
112
+ );
113
+ return await Position.loadAll(this, addresses, config);
114
+ }
115
+
116
+ public async openPosition(
117
+ owner: TransactionSigner,
118
+ positionMint: TransactionSigner,
119
+ { lowerBinId, upperBinId }: { lowerBinId: number, upperBinId: number },
120
+ ): Promise<Instruction[]> {
121
+ return await openPosition(
122
+ this.#rpc,
123
+ { owner, positionMint, pool: this.address, lowerBinId, upperBinId },
124
+ { programAddress: this.#programAddress },
125
+ );
126
+ }
127
+
128
+ public async closePosition(
129
+ owner: TransactionSigner,
130
+ positionMint: Address,
131
+ ): Promise<Instruction> {
132
+ return await closePosition(
133
+ { owner, positionMint },
134
+ { programAddress: this.#programAddress },
135
+ );
136
+ }
137
+
138
+ public async swap(
139
+ user: TransactionSigner,
140
+ {
141
+ xToY,
142
+ amountIn,
143
+ minAmountOut,
144
+ }: {
145
+ xToY: boolean,
146
+ amountIn: bigint,
147
+ minAmountOut: bigint,
148
+ }
149
+ ): Promise<Instruction[]> {
150
+ const indices = generateBinArrayIndicesForSwap(this.activeBinId, xToY, MAX_BIN_ARRAYS_PER_SWAP);
151
+ const [binArrayAddresses, {
152
+ ataX: tokenUserAccountX,
153
+ ataY: tokenUserAccountY,
154
+ preInstructions,
155
+ postInstructions,
156
+ }] = await Promise.all([
157
+ findAllBinArrayAddresses(
158
+ { pool: this.address, indices },
159
+ { programAddress: this.#programAddress },
160
+ ),
161
+ processAssociatedTokenAccountPair({
162
+ owner: user,
163
+ tokenMintX: this.tokenMintX,
164
+ tokenMintY: this.tokenMintY,
165
+ tokenProgramX: this.tokenProgramX,
166
+ tokenProgramY: this.tokenProgramY,
167
+ amountX: xToY ? amountIn : undefined,
168
+ amountY: xToY ? undefined : amountIn,
169
+ }),
170
+ ]);
171
+
172
+ const swapIx = generated.getSwapInstruction({
173
+ user,
174
+ pool: this.address,
175
+ tokenMintX: this.tokenMintX,
176
+ tokenMintY: this.tokenMintY,
177
+ tokenUserAccountX,
178
+ tokenUserAccountY,
179
+ tokenVaultX: this.tokenVaultX,
180
+ tokenVaultY: this.tokenVaultY,
181
+ tokenProgramX: this.tokenProgramX,
182
+ tokenProgramY: this.tokenProgramY,
183
+ amountIn,
184
+ minAmountOut,
185
+ xToY,
186
+ }, { programAddress: this.#programAddress });
187
+
188
+ const remainingAccounts = binArrayAddresses.map(address => ({ address, role: AccountRole.WRITABLE }));
189
+ const swapIxWithBinArrays = { ...swapIx, accounts: [...swapIx.accounts, ...remainingAccounts] };
190
+
191
+ return [...preInstructions, swapIxWithBinArrays, ...postInstructions];
192
+ }
193
+
194
+ public async quote(
195
+ {
196
+ xToY,
197
+ amountIn,
198
+ slippageToleranceBps,
199
+ }: {
200
+ xToY: boolean,
201
+ amountIn: bigint,
202
+ slippageToleranceBps: number,
203
+ }
204
+ ): Promise<QuoteOutput> {
205
+ const indices = generateBinArrayIndicesForSwap(this.activeBinId, xToY, MAX_BIN_ARRAYS_PER_SWAP);
206
+ const binArrayAddresses = await findAllBinArrayAddresses(
207
+ { pool: this.address, indices },
208
+ { programAddress: this.#programAddress },
209
+ );
210
+
211
+ const [maybeBinArrays, { epoch }] = await Promise.all([
212
+ generated.fetchAllMaybeBinArray(this.#rpc, binArrayAddresses),
213
+ this.#rpc.getEpochInfo().send(),
214
+ ]);
215
+ const binArrays = maybeBinArrays.map(maybeBinArray => maybeBinArray.exists ? maybeBinArray.data : undefined);
216
+
217
+ const transferFeeX = resolveTransferFee(this.#mintX.data, epoch);
218
+ const transferFeeY = resolveTransferFee(this.#mintY.data, epoch);
219
+
220
+ return await quote({
221
+ amountIn,
222
+ xToY,
223
+ slippageToleranceBps,
224
+ now: BigInt(Math.floor(Date.now() / 1000)),
225
+ poolState: this.data,
226
+ inputTransferFee: xToY ? transferFeeX : transferFeeY,
227
+ outputTransferFee: xToY ? transferFeeY : transferFeeX,
228
+ binArrays,
229
+ });
230
+ }
231
+
232
+ public async quoteAndSwap(
233
+ user: TransactionSigner,
234
+ {
235
+ xToY,
236
+ amountIn,
237
+ slippageToleranceBps,
238
+ }: {
239
+ xToY: boolean,
240
+ amountIn: bigint,
241
+ slippageToleranceBps: number,
242
+ }
243
+ ): Promise<{ quoteOutput: QuoteOutput, instructions: Instruction[] }> {
244
+ const quoteOutput = await this.quote({ xToY, amountIn, slippageToleranceBps });
245
+ const instructions = await this.swap(user, { xToY, amountIn, minAmountOut: quoteOutput.minAmountOut });
246
+ return { quoteOutput, instructions };
247
+ }
248
+
249
+ public async sync(
250
+ user: TransactionSigner,
251
+ desiredBinId: number,
252
+ ): Promise<Instruction[]> {
253
+ const indices = generateBinArrayIndicesForSync(this.activeBinId, desiredBinId, MAX_BIN_ARRAYS_PER_SYNC);
254
+ const binArrayAddresses = await findAllBinArrayAddresses(
255
+ { pool: this.address, indices },
256
+ { programAddress: this.#programAddress },
257
+ );
258
+
259
+ const syncPoolIx = generated.getSyncPoolInstruction(
260
+ { user, pool: this.address, desiredBinId },
261
+ { programAddress: this.#programAddress },
262
+ );
263
+ const remainingAccounts = binArrayAddresses.map(address => ({ address, role: AccountRole.READONLY }));
264
+
265
+ return [{ ...syncPoolIx, accounts: [...syncPoolIx.accounts, ...remainingAccounts] }];
266
+ }
267
+
268
+ public async setDynamicFeeConfig(
269
+ authority: TransactionSigner,
270
+ dynamicFeeConfig: generated.DynamicFeeConfig,
271
+ ): Promise<Instruction> {
272
+ const adminConfig = await resolveAdminConfigAddress(this.#programAddress);
273
+ return await generated.getSetPoolDynamicFeeConfigInstructionAsync(
274
+ { authority, pool: this.address, config: dynamicFeeConfig, adminConfig },
275
+ { programAddress: this.#programAddress },
276
+ );
277
+ }
278
+
279
+ public async setProtocolShare(
280
+ authority: TransactionSigner,
281
+ protocolShare: number,
282
+ ): Promise<Instruction> {
283
+ const adminConfig = await resolveAdminConfigAddress(this.#programAddress);
284
+ return await generated.getSetPoolProtocolShareInstructionAsync(
285
+ { authority, pool: this.address, protocolShare, adminConfig },
286
+ { programAddress: this.#programAddress },
287
+ );
288
+ }
289
+
290
+ public async claimProtocolFee(authority: TransactionSigner): Promise<Instruction[]> {
291
+ const [adminConfig, {
292
+ ataX: tokenAdminAccountX,
293
+ ataY: tokenAdminAccountY,
294
+ preInstructions,
295
+ postInstructions,
296
+ }] = await Promise.all([
297
+ resolveAdminConfigAddress(this.#programAddress),
298
+ processAssociatedTokenAccountPair({
299
+ owner: authority,
300
+ tokenMintX: this.tokenMintX,
301
+ tokenMintY: this.tokenMintY,
302
+ tokenProgramX: this.tokenProgramX,
303
+ tokenProgramY: this.tokenProgramY,
304
+ }),
305
+ ]);
306
+
307
+ const claimProtocolFeeIx = await generated.getClaimProtocolFeeInstructionAsync({
308
+ authority,
309
+ pool: this.address,
310
+ adminConfig,
311
+ tokenMintX: this.tokenMintX,
312
+ tokenMintY: this.tokenMintY,
313
+ tokenVaultX: this.tokenVaultX,
314
+ tokenVaultY: this.tokenVaultY,
315
+ tokenAdminAccountX,
316
+ tokenAdminAccountY,
317
+ tokenProgramX: this.tokenProgramX,
318
+ tokenProgramY: this.tokenProgramY,
319
+ }, { programAddress: this.#programAddress });
320
+
321
+ return [...preInstructions, claimProtocolFeeIx, ...postInstructions];
322
+ }
323
+
324
+ public static async load(
325
+ rpc: ReturnType<typeof createSolanaRpc>,
326
+ address: Address,
327
+ programAddress: Address,
328
+ config?: FetchAccountConfig,
329
+ ): Promise<Pool> {
330
+ const pool = await generated.fetchPool(rpc, address, config);
331
+ const { tokenMintX, tokenMintY } = pool.data;
332
+ const [mintX, mintY] = await fetchAllMint(rpc, [tokenMintX, tokenMintY], config);
333
+ return new Pool(
334
+ rpc,
335
+ pool,
336
+ mintX,
337
+ mintY,
338
+ programAddress,
339
+ );
340
+ }
341
+ }
342
+
343
+ export async function findPoolAddress(
344
+ seeds: { tokenMintX: Address, tokenMintY: Address, binStep: number, feeRate: number },
345
+ config: ProgramConfig,
346
+ ): Promise<Address> {
347
+ const [address] = await generated.findPoolPda(seeds, config);
348
+ return address;
349
+ }
350
+
351
+ export async function createPool(
352
+ {
353
+ authority,
354
+ binStep,
355
+ feeRate,
356
+ protocolShare,
357
+ activeBinId,
358
+ tokenMintX,
359
+ tokenMintY,
360
+ tokenProgramX,
361
+ tokenProgramY,
362
+ }: {
363
+ authority: TransactionSigner,
364
+ binStep: number,
365
+ feeRate: number,
366
+ protocolShare: number,
367
+ activeBinId: number,
368
+ tokenMintX: Address,
369
+ tokenMintY: Address,
370
+ tokenProgramX: Address,
371
+ tokenProgramY: Address,
372
+ },
373
+ config: ProgramConfig,
374
+ ): Promise<Instruction> {
375
+ const [pool, adminConfig] = await Promise.all([
376
+ findPoolAddress({ tokenMintX, tokenMintY, binStep, feeRate }, config),
377
+ resolveAdminConfigAddress(config.programAddress),
378
+ ]);
379
+ return await generated.getCreatePoolInstructionAsync({
380
+ authority,
381
+ pool,
382
+ adminConfig,
383
+ binStep,
384
+ feeRate,
385
+ protocolShare,
386
+ activeBinId,
387
+ tokenMintX,
388
+ tokenMintY,
389
+ tokenProgramX,
390
+ tokenProgramY,
391
+ }, config);
392
+ }