@liquid-af/sdk 0.1.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 (225) hide show
  1. package/README.md +776 -0
  2. package/dist/accounts/index.d.ts +5 -0
  3. package/dist/accounts/index.d.ts.map +1 -0
  4. package/dist/accounts/index.js +5 -0
  5. package/dist/accounts/index.js.map +1 -0
  6. package/dist/accounts/liquid-fees.d.ts +63 -0
  7. package/dist/accounts/liquid-fees.d.ts.map +1 -0
  8. package/dist/accounts/liquid-fees.js +27 -0
  9. package/dist/accounts/liquid-fees.js.map +1 -0
  10. package/dist/accounts/liquid-state.d.ts +112 -0
  11. package/dist/accounts/liquid-state.d.ts.map +1 -0
  12. package/dist/accounts/liquid-state.js +92 -0
  13. package/dist/accounts/liquid-state.js.map +1 -0
  14. package/dist/accounts/liquid-swap.d.ts +97 -0
  15. package/dist/accounts/liquid-swap.d.ts.map +1 -0
  16. package/dist/accounts/liquid-swap.js +54 -0
  17. package/dist/accounts/liquid-swap.js.map +1 -0
  18. package/dist/accounts/liquid.d.ts +175 -0
  19. package/dist/accounts/liquid.d.ts.map +1 -0
  20. package/dist/accounts/liquid.js +66 -0
  21. package/dist/accounts/liquid.js.map +1 -0
  22. package/dist/client.d.ts +621 -0
  23. package/dist/client.d.ts.map +1 -0
  24. package/dist/client.js +511 -0
  25. package/dist/client.js.map +1 -0
  26. package/dist/config.d.ts +56 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +44 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/errors.d.ts +39 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +63 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/events/index.d.ts +4 -0
  35. package/dist/events/index.d.ts.map +1 -0
  36. package/dist/events/index.js +2 -0
  37. package/dist/events/index.js.map +1 -0
  38. package/dist/events/parser.d.ts +40 -0
  39. package/dist/events/parser.d.ts.map +1 -0
  40. package/dist/events/parser.js +67 -0
  41. package/dist/events/parser.js.map +1 -0
  42. package/dist/events/types.d.ts +286 -0
  43. package/dist/events/types.d.ts.map +1 -0
  44. package/dist/events/types.js +2 -0
  45. package/dist/events/types.js.map +1 -0
  46. package/dist/helpers/index.d.ts +4 -0
  47. package/dist/helpers/index.d.ts.map +1 -0
  48. package/dist/helpers/index.js +3 -0
  49. package/dist/helpers/index.js.map +1 -0
  50. package/dist/helpers/preview.d.ts +259 -0
  51. package/dist/helpers/preview.d.ts.map +1 -0
  52. package/dist/helpers/preview.js +458 -0
  53. package/dist/helpers/preview.js.map +1 -0
  54. package/dist/helpers/user.d.ts +11 -0
  55. package/dist/helpers/user.d.ts.map +1 -0
  56. package/dist/helpers/user.js +20 -0
  57. package/dist/helpers/user.js.map +1 -0
  58. package/dist/idl/index.d.ts +53 -0
  59. package/dist/idl/index.d.ts.map +1 -0
  60. package/dist/idl/index.js +64 -0
  61. package/dist/idl/index.js.map +1 -0
  62. package/dist/idl/liquid.d.ts +10523 -0
  63. package/dist/idl/liquid.d.ts.map +1 -0
  64. package/dist/idl/liquid.js +2 -0
  65. package/dist/idl/liquid.js.map +1 -0
  66. package/dist/idl/liquid.json +10516 -0
  67. package/dist/idl/liquid_fees.d.ts +1520 -0
  68. package/dist/idl/liquid_fees.d.ts.map +1 -0
  69. package/dist/idl/liquid_fees.js +2 -0
  70. package/dist/idl/liquid_fees.js.map +1 -0
  71. package/dist/idl/liquid_fees.json +1513 -0
  72. package/dist/idl/liquid_state.d.ts +2936 -0
  73. package/dist/idl/liquid_state.d.ts.map +1 -0
  74. package/dist/idl/liquid_state.js +2 -0
  75. package/dist/idl/liquid_state.js.map +1 -0
  76. package/dist/idl/liquid_state.json +2929 -0
  77. package/dist/idl/liquid_swap.d.ts +5849 -0
  78. package/dist/idl/liquid_swap.d.ts.map +1 -0
  79. package/dist/idl/liquid_swap.js +2 -0
  80. package/dist/idl/liquid_swap.js.map +1 -0
  81. package/dist/idl/liquid_swap.json +5842 -0
  82. package/dist/index.d.ts +19 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +15 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/instructions/index.d.ts +9 -0
  87. package/dist/instructions/index.d.ts.map +1 -0
  88. package/dist/instructions/index.js +9 -0
  89. package/dist/instructions/index.js.map +1 -0
  90. package/dist/instructions/liquid-fees.d.ts +111 -0
  91. package/dist/instructions/liquid-fees.d.ts.map +1 -0
  92. package/dist/instructions/liquid-fees.js +169 -0
  93. package/dist/instructions/liquid-fees.js.map +1 -0
  94. package/dist/instructions/liquid-state.d.ts +173 -0
  95. package/dist/instructions/liquid-state.d.ts.map +1 -0
  96. package/dist/instructions/liquid-state.js +194 -0
  97. package/dist/instructions/liquid-state.js.map +1 -0
  98. package/dist/instructions/liquid-swap.d.ts +122 -0
  99. package/dist/instructions/liquid-swap.d.ts.map +1 -0
  100. package/dist/instructions/liquid-swap.js +167 -0
  101. package/dist/instructions/liquid-swap.js.map +1 -0
  102. package/dist/instructions/liquid.d.ts +297 -0
  103. package/dist/instructions/liquid.d.ts.map +1 -0
  104. package/dist/instructions/liquid.js +483 -0
  105. package/dist/instructions/liquid.js.map +1 -0
  106. package/dist/instructions/program-cache.d.ts +35 -0
  107. package/dist/instructions/program-cache.d.ts.map +1 -0
  108. package/dist/instructions/program-cache.js +68 -0
  109. package/dist/instructions/program-cache.js.map +1 -0
  110. package/dist/math/amm.d.ts +42 -0
  111. package/dist/math/amm.d.ts.map +1 -0
  112. package/dist/math/amm.js +109 -0
  113. package/dist/math/amm.js.map +1 -0
  114. package/dist/math/bonding-curve.d.ts +34 -0
  115. package/dist/math/bonding-curve.d.ts.map +1 -0
  116. package/dist/math/bonding-curve.js +80 -0
  117. package/dist/math/bonding-curve.js.map +1 -0
  118. package/dist/math/constants.d.ts +14 -0
  119. package/dist/math/constants.d.ts.map +1 -0
  120. package/dist/math/constants.js +14 -0
  121. package/dist/math/constants.js.map +1 -0
  122. package/dist/math/fees.d.ts +88 -0
  123. package/dist/math/fees.d.ts.map +1 -0
  124. package/dist/math/fees.js +135 -0
  125. package/dist/math/fees.js.map +1 -0
  126. package/dist/math/index.d.ts +8 -0
  127. package/dist/math/index.d.ts.map +1 -0
  128. package/dist/math/index.js +6 -0
  129. package/dist/math/index.js.map +1 -0
  130. package/dist/math/tiered-fees.d.ts +80 -0
  131. package/dist/math/tiered-fees.d.ts.map +1 -0
  132. package/dist/math/tiered-fees.js +129 -0
  133. package/dist/math/tiered-fees.js.map +1 -0
  134. package/dist/oracle.d.ts +53 -0
  135. package/dist/oracle.d.ts.map +1 -0
  136. package/dist/oracle.js +70 -0
  137. package/dist/oracle.js.map +1 -0
  138. package/dist/pda/index.d.ts +89 -0
  139. package/dist/pda/index.d.ts.map +1 -0
  140. package/dist/pda/index.js +127 -0
  141. package/dist/pda/index.js.map +1 -0
  142. package/dist/pda/liquid-fees.d.ts +27 -0
  143. package/dist/pda/liquid-fees.d.ts.map +1 -0
  144. package/dist/pda/liquid-fees.js +36 -0
  145. package/dist/pda/liquid-fees.js.map +1 -0
  146. package/dist/pda/liquid-state.d.ts +56 -0
  147. package/dist/pda/liquid-state.d.ts.map +1 -0
  148. package/dist/pda/liquid-state.js +79 -0
  149. package/dist/pda/liquid-state.js.map +1 -0
  150. package/dist/pda/liquid-swap.d.ts +76 -0
  151. package/dist/pda/liquid-swap.d.ts.map +1 -0
  152. package/dist/pda/liquid-swap.js +103 -0
  153. package/dist/pda/liquid-swap.js.map +1 -0
  154. package/dist/pda/liquid.d.ts +67 -0
  155. package/dist/pda/liquid.d.ts.map +1 -0
  156. package/dist/pda/liquid.js +91 -0
  157. package/dist/pda/liquid.js.map +1 -0
  158. package/dist/provider.d.ts +26 -0
  159. package/dist/provider.d.ts.map +1 -0
  160. package/dist/provider.js +47 -0
  161. package/dist/provider.js.map +1 -0
  162. package/dist/transaction/builder.d.ts +30 -0
  163. package/dist/transaction/builder.d.ts.map +1 -0
  164. package/dist/transaction/builder.js +48 -0
  165. package/dist/transaction/builder.js.map +1 -0
  166. package/dist/transaction/index.d.ts +3 -0
  167. package/dist/transaction/index.d.ts.map +1 -0
  168. package/dist/transaction/index.js +3 -0
  169. package/dist/transaction/index.js.map +1 -0
  170. package/dist/transaction/send.d.ts +25 -0
  171. package/dist/transaction/send.d.ts.map +1 -0
  172. package/dist/transaction/send.js +52 -0
  173. package/dist/transaction/send.js.map +1 -0
  174. package/dist/types.d.ts +311 -0
  175. package/dist/types.d.ts.map +1 -0
  176. package/dist/types.js +46 -0
  177. package/dist/types.js.map +1 -0
  178. package/package.json +112 -0
  179. package/src/accounts/index.ts +26 -0
  180. package/src/accounts/liquid-fees.ts +38 -0
  181. package/src/accounts/liquid-state.ts +134 -0
  182. package/src/accounts/liquid-swap.ts +79 -0
  183. package/src/accounts/liquid.ts +100 -0
  184. package/src/client.ts +1001 -0
  185. package/src/config.ts +91 -0
  186. package/src/errors.ts +94 -0
  187. package/src/events/index.ts +42 -0
  188. package/src/events/parser.ts +90 -0
  189. package/src/events/types.ts +310 -0
  190. package/src/helpers/index.ts +23 -0
  191. package/src/helpers/preview.ts +798 -0
  192. package/src/helpers/user.ts +24 -0
  193. package/src/idl/index.ts +94 -0
  194. package/src/idl/liquid.json +10516 -0
  195. package/src/idl/liquid.ts +10522 -0
  196. package/src/idl/liquid_fees.json +1513 -0
  197. package/src/idl/liquid_fees.ts +1519 -0
  198. package/src/idl/liquid_state.json +2929 -0
  199. package/src/idl/liquid_state.ts +2935 -0
  200. package/src/idl/liquid_swap.json +5842 -0
  201. package/src/idl/liquid_swap.ts +5848 -0
  202. package/src/index.ts +98 -0
  203. package/src/instructions/index.ts +109 -0
  204. package/src/instructions/liquid-fees.ts +289 -0
  205. package/src/instructions/liquid-state.ts +336 -0
  206. package/src/instructions/liquid-swap.ts +414 -0
  207. package/src/instructions/liquid.ts +884 -0
  208. package/src/instructions/program-cache.ts +106 -0
  209. package/src/math/amm.ts +146 -0
  210. package/src/math/bonding-curve.ts +122 -0
  211. package/src/math/constants.ts +19 -0
  212. package/src/math/fees.ts +191 -0
  213. package/src/math/index.ts +40 -0
  214. package/src/math/tiered-fees.ts +165 -0
  215. package/src/oracle.ts +97 -0
  216. package/src/pda/index.ts +331 -0
  217. package/src/pda/liquid-fees.ts +58 -0
  218. package/src/pda/liquid-state.ts +123 -0
  219. package/src/pda/liquid-swap.ts +162 -0
  220. package/src/pda/liquid.ts +152 -0
  221. package/src/provider.ts +60 -0
  222. package/src/transaction/builder.ts +80 -0
  223. package/src/transaction/index.ts +6 -0
  224. package/src/transaction/send.ts +72 -0
  225. package/src/types.ts +354 -0
@@ -0,0 +1,123 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+
3
+ const SEED_USER_PROPERTIES = Buffer.from("user_properties");
4
+ const SEED_GLOBAL_CURVE_VOLUME = Buffer.from("global_curve_volume");
5
+ const SEED_GLOBAL_AMM_VOLUME = Buffer.from("global_amm_volume");
6
+ const SEED_TOKEN_VOLUME = Buffer.from("token_volume");
7
+ const SEED_CASHBACK_CONFIG = Buffer.from("cashback_config");
8
+ const SEED_USER_SNAPSHOT = Buffer.from("user_snapshot");
9
+ const SEED_DEAL = Buffer.from("deal");
10
+
11
+ /**
12
+ * Derives the user properties PDA.
13
+ *
14
+ * @param user - User's public key
15
+ * @param programId - Liquid State program ID
16
+ * @returns Tuple of [PDA address, bump seed]
17
+ */
18
+ export const getUserPropertiesPDA = (
19
+ user: PublicKey,
20
+ programId: PublicKey
21
+ ): [PublicKey, number] => {
22
+ return PublicKey.findProgramAddressSync(
23
+ [SEED_USER_PROPERTIES, user.toBuffer()],
24
+ programId
25
+ );
26
+ };
27
+
28
+ /**
29
+ * Derives the global curve volume accumulator PDA.
30
+ *
31
+ * @param programId - Liquid State program ID
32
+ * @returns Tuple of [PDA address, bump seed]
33
+ */
34
+ export const getGlobalCurveVolumePDA = (
35
+ programId: PublicKey
36
+ ): [PublicKey, number] => {
37
+ return PublicKey.findProgramAddressSync(
38
+ [SEED_GLOBAL_CURVE_VOLUME],
39
+ programId
40
+ );
41
+ };
42
+
43
+ /**
44
+ * Derives the global AMM volume accumulator PDA.
45
+ *
46
+ * @param programId - Liquid State program ID
47
+ * @returns Tuple of [PDA address, bump seed]
48
+ */
49
+ export const getGlobalAmmVolumePDA = (
50
+ programId: PublicKey
51
+ ): [PublicKey, number] => {
52
+ return PublicKey.findProgramAddressSync(
53
+ [SEED_GLOBAL_AMM_VOLUME],
54
+ programId
55
+ );
56
+ };
57
+
58
+ /**
59
+ * Derives the token volume accumulator PDA for a mint.
60
+ *
61
+ * @param mint - Token mint address
62
+ * @param programId - Liquid State program ID
63
+ * @returns Tuple of [PDA address, bump seed]
64
+ */
65
+ export const getTokenVolumePDA = (
66
+ mint: PublicKey,
67
+ programId: PublicKey
68
+ ): [PublicKey, number] => {
69
+ return PublicKey.findProgramAddressSync(
70
+ [SEED_TOKEN_VOLUME, mint.toBuffer()],
71
+ programId
72
+ );
73
+ };
74
+
75
+ /**
76
+ * Derives the cashback config PDA.
77
+ *
78
+ * @param programId - Liquid State program ID
79
+ * @returns Tuple of [PDA address, bump seed]
80
+ */
81
+ export const getCashbackConfigPDA = (
82
+ programId: PublicKey
83
+ ): [PublicKey, number] => {
84
+ return PublicKey.findProgramAddressSync([SEED_CASHBACK_CONFIG], programId);
85
+ };
86
+
87
+ /**
88
+ * Derives the user snapshot PDA for a given user and index.
89
+ *
90
+ * @param user - User's public key
91
+ * @param index - Snapshot index (0-based)
92
+ * @param programId - Liquid State program ID
93
+ * @returns Tuple of [PDA address, bump seed]
94
+ */
95
+ export const getUserSnapshotPDA = (
96
+ user: PublicKey,
97
+ index: number,
98
+ programId: PublicKey
99
+ ): [PublicKey, number] => {
100
+ const indexBuffer = Buffer.alloc(4);
101
+ indexBuffer.writeUInt32LE(index);
102
+ return PublicKey.findProgramAddressSync(
103
+ [SEED_USER_SNAPSHOT, user.toBuffer(), indexBuffer],
104
+ programId
105
+ );
106
+ };
107
+
108
+ /**
109
+ * Derives the deal PDA for a given owner.
110
+ *
111
+ * @param owner - Deal owner's public key
112
+ * @param programId - Liquid State program ID
113
+ * @returns Tuple of [PDA address, bump seed]
114
+ */
115
+ export const getDealPDA = (
116
+ owner: PublicKey,
117
+ programId: PublicKey
118
+ ): [PublicKey, number] => {
119
+ return PublicKey.findProgramAddressSync(
120
+ [SEED_DEAL, owner.toBuffer()],
121
+ programId
122
+ );
123
+ };
@@ -0,0 +1,162 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+
3
+ const SEED_GLOBAL_CONFIG = Buffer.from("global_config");
4
+ const AUTH_SEED = Buffer.from("vault_and_lp_mint_auth_seed");
5
+ const POOL_SEED = Buffer.from("pool");
6
+ const POOL_LP_MINT_SEED = Buffer.from("pool_lp_mint");
7
+ const POOL_VAULT_SEED = Buffer.from("pool_vault");
8
+ const OBSERVATION_SEED = Buffer.from("observation");
9
+ const GLOBAL_FEE_SEED = Buffer.from("global_fee");
10
+ const SEED_TEMP_WSOL = Buffer.from("temp_wsol");
11
+ const SEED_BUYBACK_VAULT = Buffer.from("buyback_vault");
12
+
13
+ /**
14
+ * Derives the swap global configuration PDA.
15
+ *
16
+ * @param programId - Liquid Swap program ID
17
+ * @returns Tuple of [PDA address, bump seed]
18
+ */
19
+ export const getSwapGlobalConfigPDA = (
20
+ programId: PublicKey
21
+ ): [PublicKey, number] => {
22
+ return PublicKey.findProgramAddressSync([SEED_GLOBAL_CONFIG], programId);
23
+ };
24
+
25
+ /**
26
+ * Derives the swap authority PDA (for vaults and LP mint).
27
+ *
28
+ * @param programId - Liquid Swap program ID
29
+ * @returns Tuple of [PDA address, bump seed]
30
+ */
31
+ export const getSwapAuthorityPDA = (
32
+ programId: PublicKey
33
+ ): [PublicKey, number] => {
34
+ return PublicKey.findProgramAddressSync([AUTH_SEED], programId);
35
+ };
36
+
37
+ /**
38
+ * Derives the pool state PDA.
39
+ *
40
+ * @param baseMint - Base token mint address
41
+ * @param quoteMint - Quote token mint address
42
+ * @param programId - Liquid Swap program ID
43
+ * @returns Tuple of [PDA address, bump seed]
44
+ */
45
+ export const getPoolPDA = (
46
+ baseMint: PublicKey,
47
+ quoteMint: PublicKey,
48
+ programId: PublicKey
49
+ ): [PublicKey, number] => {
50
+ return PublicKey.findProgramAddressSync(
51
+ [POOL_SEED, baseMint.toBuffer(), quoteMint.toBuffer()],
52
+ programId
53
+ );
54
+ };
55
+
56
+ /**
57
+ * Derives the LP mint PDA for a pool.
58
+ *
59
+ * @param poolState - Pool state PDA address
60
+ * @param programId - Liquid Swap program ID
61
+ * @returns Tuple of [PDA address, bump seed]
62
+ */
63
+ export const getPoolLpMintPDA = (
64
+ poolState: PublicKey,
65
+ programId: PublicKey
66
+ ): [PublicKey, number] => {
67
+ return PublicKey.findProgramAddressSync(
68
+ [POOL_LP_MINT_SEED, poolState.toBuffer()],
69
+ programId
70
+ );
71
+ };
72
+
73
+ /**
74
+ * Derives the pool vault PDA for a specific token.
75
+ *
76
+ * @param poolState - Pool state PDA address
77
+ * @param mint - Token mint address for this vault
78
+ * @param programId - Liquid Swap program ID
79
+ * @returns Tuple of [PDA address, bump seed]
80
+ */
81
+ export const getPoolVaultPDA = (
82
+ poolState: PublicKey,
83
+ mint: PublicKey,
84
+ programId: PublicKey
85
+ ): [PublicKey, number] => {
86
+ return PublicKey.findProgramAddressSync(
87
+ [POOL_VAULT_SEED, poolState.toBuffer(), mint.toBuffer()],
88
+ programId
89
+ );
90
+ };
91
+
92
+ /**
93
+ * Derives the observation state PDA (oracle data).
94
+ *
95
+ * @param poolState - Pool state PDA address
96
+ * @param programId - Liquid Swap program ID
97
+ * @returns Tuple of [PDA address, bump seed]
98
+ */
99
+ export const getObservationPDA = (
100
+ poolState: PublicKey,
101
+ programId: PublicKey
102
+ ): [PublicKey, number] => {
103
+ return PublicKey.findProgramAddressSync(
104
+ [OBSERVATION_SEED, poolState.toBuffer()],
105
+ programId
106
+ );
107
+ };
108
+
109
+ /**
110
+ * Derives the protocol fee vault PDA.
111
+ *
112
+ * @param feeRecipient - Fee recipient's public key
113
+ * @param quoteMint - Quote token mint address
114
+ * @param programId - Liquid Swap program ID
115
+ * @returns Tuple of [PDA address, bump seed]
116
+ */
117
+ export const getProtocolFeeVaultPDA = (
118
+ feeRecipient: PublicKey,
119
+ quoteMint: PublicKey,
120
+ programId: PublicKey
121
+ ): [PublicKey, number] => {
122
+ return PublicKey.findProgramAddressSync(
123
+ [GLOBAL_FEE_SEED, feeRecipient.toBuffer(), quoteMint.toBuffer()],
124
+ programId
125
+ );
126
+ };
127
+
128
+ /**
129
+ * Derives the temporary WSOL PDA (for unwrapping during swaps).
130
+ *
131
+ * @param poolState - Pool state PDA address
132
+ * @param programId - Liquid Swap program ID
133
+ * @returns Tuple of [PDA address, bump seed]
134
+ */
135
+ export const getTempWsolPDA = (
136
+ poolState: PublicKey,
137
+ programId: PublicKey
138
+ ): [PublicKey, number] => {
139
+ return PublicKey.findProgramAddressSync(
140
+ [SEED_TEMP_WSOL, poolState.toBuffer()],
141
+ programId
142
+ );
143
+ };
144
+
145
+ /**
146
+ * Derives the buyback vault PDA for a pool.
147
+ *
148
+ * @param poolState - Pool state PDA address
149
+ * @param quoteMint - Quote token mint address
150
+ * @param programId - Liquid Swap program ID
151
+ * @returns Tuple of [PDA address, bump seed]
152
+ */
153
+ export const getSwapBuybackVaultPDA = (
154
+ poolState: PublicKey,
155
+ quoteMint: PublicKey,
156
+ programId: PublicKey
157
+ ): [PublicKey, number] => {
158
+ return PublicKey.findProgramAddressSync(
159
+ [SEED_BUYBACK_VAULT, poolState.toBuffer(), quoteMint.toBuffer()],
160
+ programId
161
+ );
162
+ };
@@ -0,0 +1,152 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ getAssociatedTokenAddressSync,
4
+ TOKEN_PROGRAM_ID,
5
+ TOKEN_2022_PROGRAM_ID,
6
+ } from "@solana/spl-token";
7
+
8
+ const SEED_GLOBAL_CONFIG = Buffer.from("global_config");
9
+ const SEED_BONDING_CURVE = Buffer.from("bonding_curve");
10
+ const SEED_BONDING_CURVE_SOL_VAULT = Buffer.from("bonding_curve_sol_vault");
11
+ const SEED_REFERRAL_VAULT = Buffer.from("referral_vault");
12
+ const SEED_BUYBACK_VAULT = Buffer.from("buyback_vault");
13
+ const SEED_TOKEN_BONDING_CURVE = Buffer.from("token_bonding_curve");
14
+
15
+ /**
16
+ * Derives the global configuration PDA for the liquid program.
17
+ *
18
+ * @param programId - Liquid program ID
19
+ * @returns Tuple of [PDA address, bump seed]
20
+ */
21
+ export const getLiquidGlobalConfigPDA = (
22
+ programId: PublicKey
23
+ ): [PublicKey, number] => {
24
+ return PublicKey.findProgramAddressSync([SEED_GLOBAL_CONFIG], programId);
25
+ };
26
+
27
+ /**
28
+ * Derives the bonding curve PDA for a token mint.
29
+ *
30
+ * @param mint - Token mint address
31
+ * @param programId - Liquid program ID
32
+ * @returns Tuple of [PDA address, bump seed]
33
+ */
34
+ export const getBondingCurvePDA = (
35
+ mint: PublicKey,
36
+ programId: PublicKey
37
+ ): [PublicKey, number] => {
38
+ return PublicKey.findProgramAddressSync(
39
+ [SEED_BONDING_CURVE, mint.toBuffer()],
40
+ programId
41
+ );
42
+ };
43
+
44
+ /**
45
+ * Derives the bonding curve SOL vault PDA.
46
+ *
47
+ * @param bondingCurve - Bonding curve PDA address
48
+ * @param programId - Liquid program ID
49
+ * @returns Tuple of [PDA address, bump seed]
50
+ */
51
+ export const getBondingCurveSolVaultPDA = (
52
+ bondingCurve: PublicKey,
53
+ programId: PublicKey
54
+ ): [PublicKey, number] => {
55
+ return PublicKey.findProgramAddressSync(
56
+ [SEED_BONDING_CURVE_SOL_VAULT, bondingCurve.toBuffer()],
57
+ programId
58
+ );
59
+ };
60
+
61
+ /**
62
+ * Derives the referral vault PDA for referral rewards.
63
+ *
64
+ * @param referrer - Referrer's public key
65
+ * @param programId - Liquid program ID
66
+ * @returns Tuple of [PDA address, bump seed]
67
+ */
68
+ export const getReferralVaultPDA = (
69
+ referrer: PublicKey,
70
+ programId: PublicKey
71
+ ): [PublicKey, number] => {
72
+ return PublicKey.findProgramAddressSync(
73
+ [SEED_REFERRAL_VAULT, referrer.toBuffer()],
74
+ programId
75
+ );
76
+ };
77
+
78
+ /**
79
+ * Derives the referral token vault (ATA) for stable curve referral rewards.
80
+ *
81
+ * @param referrer - Referrer's public key
82
+ * @param quoteMint - Quote token mint address
83
+ * @returns Associated token account address
84
+ */
85
+ export const getReferralTokenVault = (
86
+ referrer: PublicKey,
87
+ quoteMint: PublicKey
88
+ ): PublicKey => {
89
+ return getAssociatedTokenAddressSync(
90
+ quoteMint,
91
+ referrer,
92
+ false,
93
+ TOKEN_PROGRAM_ID
94
+ );
95
+ };
96
+
97
+ /**
98
+ * Derives the buyback vault PDA for a bonding curve.
99
+ *
100
+ * @param bondingCurve - Bonding curve PDA address
101
+ * @param programId - Liquid program ID
102
+ * @returns Tuple of [PDA address, bump seed]
103
+ */
104
+ export const getBuybackVaultPDA = (
105
+ bondingCurve: PublicKey,
106
+ programId: PublicKey
107
+ ): [PublicKey, number] => {
108
+ return PublicKey.findProgramAddressSync(
109
+ [SEED_BUYBACK_VAULT, bondingCurve.toBuffer()],
110
+ programId
111
+ );
112
+ };
113
+
114
+ /**
115
+ * Derives the token-based bonding curve PDA for a token mint and quote mint.
116
+ *
117
+ * @param mint - Token mint address
118
+ * @param quoteMint - Quote token mint address
119
+ * @param programId - Liquid program ID
120
+ * @returns Tuple of [PDA address, bump seed]
121
+ */
122
+ export const getStableBondingCurvePDA = (
123
+ mint: PublicKey,
124
+ quoteMint: PublicKey,
125
+ programId: PublicKey
126
+ ): [PublicKey, number] => {
127
+ return PublicKey.findProgramAddressSync(
128
+ [SEED_TOKEN_BONDING_CURVE, mint.toBuffer(), quoteMint.toBuffer()],
129
+ programId
130
+ );
131
+ };
132
+
133
+ /**
134
+ * Derives the bonding curve's token account (ATA) for holding minted tokens.
135
+ * Uses Token-2022 since bonding curve mints use the Token-2022 program.
136
+ *
137
+ * @param mint - Token mint address
138
+ * @param programId - Liquid program ID
139
+ * @returns Associated token account address
140
+ */
141
+ export const getBondingCurveTokenAccount = (
142
+ mint: PublicKey,
143
+ programId: PublicKey
144
+ ): PublicKey => {
145
+ const [bondingCurve] = getBondingCurvePDA(mint, programId);
146
+ return getAssociatedTokenAddressSync(
147
+ mint,
148
+ bondingCurve,
149
+ true,
150
+ TOKEN_2022_PROGRAM_ID
151
+ );
152
+ };
@@ -0,0 +1,60 @@
1
+ import { AnchorProvider } from "@coral-xyz/anchor";
2
+ import {
3
+ Connection,
4
+ PublicKey,
5
+ type Transaction,
6
+ type VersionedTransaction,
7
+ } from "@solana/web3.js";
8
+
9
+ /**
10
+ * A wallet that satisfies Anchor's Wallet interface via structural typing,
11
+ * without requiring a Keypair. Used for read-only operations (account fetching)
12
+ * and instruction building where no actual signing is needed.
13
+ */
14
+ export class ReadonlyWallet {
15
+ readonly publicKey = PublicKey.default;
16
+
17
+ /** @throws Always throws — signing is not supported on a read-only wallet. */
18
+ async signTransaction<T extends Transaction | VersionedTransaction>(
19
+ _tx: T
20
+ ): Promise<T> {
21
+ throw new Error("Cannot sign with a readonly provider");
22
+ }
23
+
24
+ /** @throws Always throws — signing is not supported on a read-only wallet. */
25
+ async signAllTransactions<T extends Transaction | VersionedTransaction>(
26
+ _txs: T[]
27
+ ): Promise<T[]> {
28
+ throw new Error("Cannot sign with a readonly provider");
29
+ }
30
+ }
31
+
32
+ const readonlyWallet = new ReadonlyWallet();
33
+
34
+ /**
35
+ * Creates an AnchorProvider for read-only operations (account fetching).
36
+ * Uses a real Connection but a dummy wallet that throws on sign attempts.
37
+ */
38
+ export function createReadonlyProvider(connection: Connection): AnchorProvider {
39
+ return new AnchorProvider(connection, readonlyWallet, {
40
+ commitment: "confirmed",
41
+ preflightCommitment: "confirmed",
42
+ });
43
+ }
44
+
45
+ let stubProvider: AnchorProvider | null = null;
46
+
47
+ /**
48
+ * Returns a cached stub AnchorProvider for instruction building.
49
+ * Instruction building via `.instruction()` never hits the network,
50
+ * so no real Connection is needed.
51
+ */
52
+ export function createStubProvider(): AnchorProvider {
53
+ if (!stubProvider) {
54
+ const stubConnection = new Connection("http://stub.invalid");
55
+ stubProvider = new AnchorProvider(stubConnection, readonlyWallet, {
56
+ commitment: "confirmed",
57
+ });
58
+ }
59
+ return stubProvider;
60
+ }
@@ -0,0 +1,80 @@
1
+ import {
2
+ ComputeBudgetProgram,
3
+ Transaction,
4
+ type Connection,
5
+ type PublicKey,
6
+ type TransactionInstruction,
7
+ } from "@solana/web3.js";
8
+
9
+ export interface BuildTransactionOptions {
10
+ /** The public key of the fee payer */
11
+ feePayer: PublicKey;
12
+ /** Compute unit limit (omit to let the runtime decide) */
13
+ computeUnits?: number;
14
+ /** Priority fee in micro-lamports per compute unit */
15
+ priorityFee?: number;
16
+ }
17
+
18
+ /**
19
+ * Prepends compute budget instructions to an instruction list.
20
+ * Returns a new array; does not mutate the input.
21
+ *
22
+ * @param instructions - Transaction instructions to prepend budget to
23
+ * @param options - Compute unit limit and/or priority fee
24
+ * @returns New instruction array with budget instructions prepended
25
+ */
26
+ export function withComputeBudget(
27
+ instructions: TransactionInstruction[],
28
+ options: Pick<BuildTransactionOptions, "computeUnits" | "priorityFee">
29
+ ): TransactionInstruction[] {
30
+ const budget: TransactionInstruction[] = [];
31
+ if (options.computeUnits !== undefined) {
32
+ budget.push(
33
+ ComputeBudgetProgram.setComputeUnitLimit({
34
+ units: options.computeUnits,
35
+ })
36
+ );
37
+ }
38
+ if (options.priorityFee !== undefined) {
39
+ budget.push(
40
+ ComputeBudgetProgram.setComputeUnitPrice({
41
+ microLamports: options.priorityFee,
42
+ })
43
+ );
44
+ }
45
+ return [...budget, ...instructions];
46
+ }
47
+
48
+ /**
49
+ * Builds an unsigned Transaction from one or more instructions.
50
+ * Fetches a recent blockhash and sets the fee payer. The caller is
51
+ * responsible for signing.
52
+ *
53
+ * @param connection - Solana RPC connection
54
+ * @param instructions - Transaction instructions to include
55
+ * @param options - Fee payer and optional compute budget settings
56
+ * @returns Unsigned transaction ready for signing
57
+ */
58
+ export async function buildTransaction(
59
+ connection: Connection,
60
+ instructions: TransactionInstruction[],
61
+ options: BuildTransactionOptions
62
+ ): Promise<Transaction> {
63
+ const { feePayer, ...budgetOptions } = options;
64
+ const allIxs =
65
+ budgetOptions.computeUnits !== undefined ||
66
+ budgetOptions.priorityFee !== undefined
67
+ ? withComputeBudget(instructions, budgetOptions)
68
+ : instructions;
69
+
70
+ const { blockhash, lastValidBlockHeight } =
71
+ await connection.getLatestBlockhash();
72
+
73
+ const tx = new Transaction();
74
+ tx.add(...allIxs);
75
+ tx.recentBlockhash = blockhash;
76
+ tx.lastValidBlockHeight = lastValidBlockHeight;
77
+ tx.feePayer = feePayer;
78
+
79
+ return tx;
80
+ }
@@ -0,0 +1,6 @@
1
+ export { confirmTx, sendAndConfirm } from "./send.js";
2
+ export {
3
+ withComputeBudget,
4
+ buildTransaction,
5
+ type BuildTransactionOptions,
6
+ } from "./builder.js";
@@ -0,0 +1,72 @@
1
+ import type { Connection } from "@solana/web3.js";
2
+
3
+ /**
4
+ * Confirms a transaction with the given signature and blockhash info.
5
+ *
6
+ * @param connection - Solana RPC connection
7
+ * @param signature - Transaction signature to confirm
8
+ * @param blockhash - Recent blockhash used in the transaction
9
+ * @param lastValidBlockHeight - Block height after which the transaction expires
10
+ * @returns The confirmed transaction signature
11
+ */
12
+ export const confirmTx = async (
13
+ connection: Connection,
14
+ signature: string,
15
+ blockhash: string,
16
+ lastValidBlockHeight: number
17
+ ): Promise<string> => {
18
+ await connection.confirmTransaction(
19
+ { blockhash, lastValidBlockHeight, signature },
20
+ "confirmed"
21
+ );
22
+ return signature;
23
+ };
24
+
25
+ /**
26
+ * Executes an RPC call and confirms the transaction.
27
+ *
28
+ * Handles Anchor's legacy 30s confirmation timeout: if .rpc() throws a
29
+ * TransactionExpiredTimeoutError the transaction may still have landed.
30
+ * We extract the signature from the error and re-check status before
31
+ * propagating the failure.
32
+ *
33
+ * @param connection - Solana RPC connection
34
+ * @param rpcCall - Async function that sends the transaction and returns its signature
35
+ * @returns The confirmed transaction signature
36
+ */
37
+ export const sendAndConfirm = async (
38
+ connection: Connection,
39
+ rpcCall: () => Promise<string>
40
+ ): Promise<string> => {
41
+ try {
42
+ const signature = await rpcCall();
43
+ const { blockhash, lastValidBlockHeight } =
44
+ await connection.getLatestBlockhash();
45
+ await confirmTx(connection, signature, blockhash, lastValidBlockHeight);
46
+ return signature;
47
+ } catch (err: unknown) {
48
+ if (
49
+ err &&
50
+ typeof err === "object" &&
51
+ "signature" in err &&
52
+ typeof (err as Record<string, unknown>).signature === "string"
53
+ ) {
54
+ const sig = (err as Record<string, unknown>).signature as string;
55
+ await new Promise((r) => setTimeout(r, 2000));
56
+ try {
57
+ const { blockhash, lastValidBlockHeight } =
58
+ await connection.getLatestBlockhash();
59
+ await confirmTx(
60
+ connection,
61
+ sig,
62
+ blockhash,
63
+ lastValidBlockHeight
64
+ );
65
+ return sig;
66
+ } catch {
67
+ // Re-confirmation also failed - throw the original error
68
+ }
69
+ }
70
+ throw err;
71
+ }
72
+ };