@coffer_so/sdk 1.0.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 (228) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/clients/AdminClient.d.ts +194 -0
  4. package/dist/clients/AdminClient.d.ts.map +1 -0
  5. package/dist/clients/AdminClient.js +482 -0
  6. package/dist/clients/AdminClient.js.map +1 -0
  7. package/dist/clients/CofferBackendClient.d.ts +877 -0
  8. package/dist/clients/CofferBackendClient.d.ts.map +1 -0
  9. package/dist/clients/CofferBackendClient.js +536 -0
  10. package/dist/clients/CofferBackendClient.js.map +1 -0
  11. package/dist/clients/CubeBackendClient.d.ts +877 -0
  12. package/dist/clients/CubeBackendClient.d.ts.map +1 -0
  13. package/dist/clients/CubeBackendClient.js +536 -0
  14. package/dist/clients/CubeBackendClient.js.map +1 -0
  15. package/dist/clients/CubicPoolClient.d.ts +120 -0
  16. package/dist/clients/CubicPoolClient.d.ts.map +1 -0
  17. package/dist/clients/CubicPoolClient.js +687 -0
  18. package/dist/clients/CubicPoolClient.js.map +1 -0
  19. package/dist/clients/PoolFactoryClient.d.ts +53 -0
  20. package/dist/clients/PoolFactoryClient.d.ts.map +1 -0
  21. package/dist/clients/PoolFactoryClient.js +91 -0
  22. package/dist/clients/PoolFactoryClient.js.map +1 -0
  23. package/dist/clients/RpcClient.d.ts +49 -0
  24. package/dist/clients/RpcClient.d.ts.map +1 -0
  25. package/dist/clients/RpcClient.js +135 -0
  26. package/dist/clients/RpcClient.js.map +1 -0
  27. package/dist/clients/SingleTokenDepositClient.d.ts +67 -0
  28. package/dist/clients/SingleTokenDepositClient.d.ts.map +1 -0
  29. package/dist/clients/SingleTokenDepositClient.js +105 -0
  30. package/dist/clients/SingleTokenDepositClient.js.map +1 -0
  31. package/dist/clients/contract-instructions.d.ts +24 -0
  32. package/dist/clients/contract-instructions.d.ts.map +1 -0
  33. package/dist/clients/contract-instructions.js +130 -0
  34. package/dist/clients/contract-instructions.js.map +1 -0
  35. package/dist/clients/index.d.ts +10 -0
  36. package/dist/clients/index.d.ts.map +1 -0
  37. package/dist/clients/index.js +26 -0
  38. package/dist/clients/index.js.map +1 -0
  39. package/dist/clients/quote-math.d.ts +15 -0
  40. package/dist/clients/quote-math.d.ts.map +1 -0
  41. package/dist/clients/quote-math.js +98 -0
  42. package/dist/clients/quote-math.js.map +1 -0
  43. package/dist/clients/tx-builders.d.ts +231 -0
  44. package/dist/clients/tx-builders.d.ts.map +1 -0
  45. package/dist/clients/tx-builders.js +861 -0
  46. package/dist/clients/tx-builders.js.map +1 -0
  47. package/dist/clients/versioned.d.ts +34 -0
  48. package/dist/clients/versioned.d.ts.map +1 -0
  49. package/dist/clients/versioned.js +55 -0
  50. package/dist/clients/versioned.js.map +1 -0
  51. package/dist/config/index.d.ts +65 -0
  52. package/dist/config/index.d.ts.map +1 -0
  53. package/dist/config/index.js +75 -0
  54. package/dist/config/index.js.map +1 -0
  55. package/dist/config/networks.d.ts +12 -0
  56. package/dist/config/networks.d.ts.map +1 -0
  57. package/dist/config/networks.js +51 -0
  58. package/dist/config/networks.js.map +1 -0
  59. package/dist/config/tokens.d.ts +19 -0
  60. package/dist/config/tokens.d.ts.map +1 -0
  61. package/dist/config/tokens.js +43 -0
  62. package/dist/config/tokens.js.map +1 -0
  63. package/dist/idl/cubic_pool.json +4203 -0
  64. package/dist/idl/index.d.ts +1769 -0
  65. package/dist/idl/index.d.ts.map +1 -0
  66. package/dist/idl/index.js +18 -0
  67. package/dist/idl/index.js.map +1 -0
  68. package/dist/idl/protocol_admin.json +2615 -0
  69. package/dist/idl/single_token_liquidity.json +1121 -0
  70. package/dist/index.d.ts +75 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +206 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/math/cubicMath.d.ts +40 -0
  75. package/dist/math/cubicMath.d.ts.map +1 -0
  76. package/dist/math/cubicMath.js +82 -0
  77. package/dist/math/cubicMath.js.map +1 -0
  78. package/dist/math/fixedPoint.d.ts +19 -0
  79. package/dist/math/fixedPoint.d.ts.map +1 -0
  80. package/dist/math/fixedPoint.js +86 -0
  81. package/dist/math/fixedPoint.js.map +1 -0
  82. package/dist/math/index.d.ts +9 -0
  83. package/dist/math/index.d.ts.map +1 -0
  84. package/dist/math/index.js +30 -0
  85. package/dist/math/index.js.map +1 -0
  86. package/dist/math/logExp.d.ts +6 -0
  87. package/dist/math/logExp.d.ts.map +1 -0
  88. package/dist/math/logExp.js +68 -0
  89. package/dist/math/logExp.js.map +1 -0
  90. package/dist/math/lpLoss.d.ts +44 -0
  91. package/dist/math/lpLoss.d.ts.map +1 -0
  92. package/dist/math/lpLoss.js +103 -0
  93. package/dist/math/lpLoss.js.map +1 -0
  94. package/dist/math/maxSelloff.d.ts +164 -0
  95. package/dist/math/maxSelloff.d.ts.map +1 -0
  96. package/dist/math/maxSelloff.js +397 -0
  97. package/dist/math/maxSelloff.js.map +1 -0
  98. package/dist/math/singleToken.d.ts +54 -0
  99. package/dist/math/singleToken.d.ts.map +1 -0
  100. package/dist/math/singleToken.js +188 -0
  101. package/dist/math/singleToken.js.map +1 -0
  102. package/dist/math/slippage.d.ts +13 -0
  103. package/dist/math/slippage.d.ts.map +1 -0
  104. package/dist/math/slippage.js +44 -0
  105. package/dist/math/slippage.js.map +1 -0
  106. package/dist/math/surgeFee.d.ts +24 -0
  107. package/dist/math/surgeFee.d.ts.map +1 -0
  108. package/dist/math/surgeFee.js +85 -0
  109. package/dist/math/surgeFee.js.map +1 -0
  110. package/dist/math/weightedMath.d.ts +20 -0
  111. package/dist/math/weightedMath.d.ts.map +1 -0
  112. package/dist/math/weightedMath.js +66 -0
  113. package/dist/math/weightedMath.js.map +1 -0
  114. package/dist/parsers/borsh.d.ts +28 -0
  115. package/dist/parsers/borsh.d.ts.map +1 -0
  116. package/dist/parsers/borsh.js +104 -0
  117. package/dist/parsers/borsh.js.map +1 -0
  118. package/dist/parsers/contracts.d.ts +26 -0
  119. package/dist/parsers/contracts.d.ts.map +1 -0
  120. package/dist/parsers/contracts.js +62 -0
  121. package/dist/parsers/contracts.js.map +1 -0
  122. package/dist/parsers/events.d.ts +3 -0
  123. package/dist/parsers/events.d.ts.map +1 -0
  124. package/dist/parsers/events.js +281 -0
  125. package/dist/parsers/events.js.map +1 -0
  126. package/dist/parsers/index.d.ts +6 -0
  127. package/dist/parsers/index.d.ts.map +1 -0
  128. package/dist/parsers/index.js +22 -0
  129. package/dist/parsers/index.js.map +1 -0
  130. package/dist/parsers/mintAccount.d.ts +24 -0
  131. package/dist/parsers/mintAccount.d.ts.map +1 -0
  132. package/dist/parsers/mintAccount.js +27 -0
  133. package/dist/parsers/mintAccount.js.map +1 -0
  134. package/dist/parsers/poolAccount.d.ts +141 -0
  135. package/dist/parsers/poolAccount.d.ts.map +1 -0
  136. package/dist/parsers/poolAccount.js +224 -0
  137. package/dist/parsers/poolAccount.js.map +1 -0
  138. package/dist/types/contracts.d.ts +1340 -0
  139. package/dist/types/contracts.d.ts.map +1 -0
  140. package/dist/types/contracts.js +3 -0
  141. package/dist/types/contracts.js.map +1 -0
  142. package/dist/types/events.d.ts +172 -0
  143. package/dist/types/events.d.ts.map +1 -0
  144. package/dist/types/events.js +3 -0
  145. package/dist/types/events.js.map +1 -0
  146. package/dist/types/index.d.ts +6 -0
  147. package/dist/types/index.d.ts.map +1 -0
  148. package/dist/types/index.js +22 -0
  149. package/dist/types/index.js.map +1 -0
  150. package/dist/types/pool.d.ts +149 -0
  151. package/dist/types/pool.d.ts.map +1 -0
  152. package/dist/types/pool.js +3 -0
  153. package/dist/types/pool.js.map +1 -0
  154. package/dist/types/result.d.ts +24 -0
  155. package/dist/types/result.d.ts.map +1 -0
  156. package/dist/types/result.js +11 -0
  157. package/dist/types/result.js.map +1 -0
  158. package/dist/types/tx.d.ts +261 -0
  159. package/dist/types/tx.d.ts.map +1 -0
  160. package/dist/types/tx.js +3 -0
  161. package/dist/types/tx.js.map +1 -0
  162. package/dist/utils/errors.d.ts +44 -0
  163. package/dist/utils/errors.d.ts.map +1 -0
  164. package/dist/utils/errors.js +192 -0
  165. package/dist/utils/errors.js.map +1 -0
  166. package/dist/utils/extensions.d.ts +98 -0
  167. package/dist/utils/extensions.d.ts.map +1 -0
  168. package/dist/utils/extensions.js +187 -0
  169. package/dist/utils/extensions.js.map +1 -0
  170. package/dist/utils/index.d.ts +5 -0
  171. package/dist/utils/index.d.ts.map +1 -0
  172. package/dist/utils/index.js +21 -0
  173. package/dist/utils/index.js.map +1 -0
  174. package/dist/utils/pda.d.ts +8 -0
  175. package/dist/utils/pda.d.ts.map +1 -0
  176. package/dist/utils/pda.js +27 -0
  177. package/dist/utils/pda.js.map +1 -0
  178. package/dist/utils/retry.d.ts +22 -0
  179. package/dist/utils/retry.d.ts.map +1 -0
  180. package/dist/utils/retry.js +62 -0
  181. package/dist/utils/retry.js.map +1 -0
  182. package/package.json +54 -0
  183. package/src/clients/AdminClient.ts +608 -0
  184. package/src/clients/CofferBackendClient.ts +1413 -0
  185. package/src/clients/CubicPoolClient.ts +719 -0
  186. package/src/clients/PoolFactoryClient.ts +110 -0
  187. package/src/clients/RpcClient.ts +195 -0
  188. package/src/clients/SingleTokenDepositClient.ts +143 -0
  189. package/src/clients/contract-instructions.ts +115 -0
  190. package/src/clients/index.ts +9 -0
  191. package/src/clients/quote-math.ts +81 -0
  192. package/src/clients/tx-builders.ts +1096 -0
  193. package/src/clients/versioned.ts +80 -0
  194. package/src/config/index.ts +111 -0
  195. package/src/config/networks.ts +71 -0
  196. package/src/config/tokens.ts +52 -0
  197. package/src/idl/cubic_pool.json +4203 -0
  198. package/src/idl/index.ts +13 -0
  199. package/src/idl/protocol_admin.json +2615 -0
  200. package/src/idl/single_token_liquidity.json +1121 -0
  201. package/src/index.ts +262 -0
  202. package/src/math/cubicMath.ts +92 -0
  203. package/src/math/fixedPoint.ts +71 -0
  204. package/src/math/index.ts +13 -0
  205. package/src/math/logExp.ts +61 -0
  206. package/src/math/lpLoss.ts +160 -0
  207. package/src/math/maxSelloff.ts +564 -0
  208. package/src/math/singleToken.ts +251 -0
  209. package/src/math/slippage.ts +38 -0
  210. package/src/math/surgeFee.ts +101 -0
  211. package/src/math/weightedMath.ts +64 -0
  212. package/src/parsers/borsh.ts +106 -0
  213. package/src/parsers/contracts.ts +64 -0
  214. package/src/parsers/events.ts +275 -0
  215. package/src/parsers/index.ts +5 -0
  216. package/src/parsers/mintAccount.ts +44 -0
  217. package/src/parsers/poolAccount.ts +372 -0
  218. package/src/types/contracts.ts +238 -0
  219. package/src/types/events.ts +198 -0
  220. package/src/types/index.ts +5 -0
  221. package/src/types/pool.ts +147 -0
  222. package/src/types/result.ts +51 -0
  223. package/src/types/tx.ts +278 -0
  224. package/src/utils/errors.ts +210 -0
  225. package/src/utils/extensions.ts +196 -0
  226. package/src/utils/index.ts +4 -0
  227. package/src/utils/pda.ts +58 -0
  228. package/src/utils/retry.ts +85 -0
package/src/index.ts ADDED
@@ -0,0 +1,262 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Copyright (c) 2026 Endgame AMM DEX Foundation.
3
+ // See LICENSE at the repository root.
4
+
5
+ /**
6
+ * @coffer_so/sdk — client library for the Cubic Pool AMM on Solana.
7
+ *
8
+ * Entry point barrel. Most consumers will want to import from this root:
9
+ *
10
+ * ```ts
11
+ * import { CubicPoolClient, CofferBackendClient, getConfig } from "@coffer_so/sdk";
12
+ *
13
+ * const cfg = getConfig("mainnet", { backendEndpoint: "https://api.coffer.so" });
14
+ * const pool = new CubicPoolClient({ config: cfg, poolAddress });
15
+ * const info = await pool.sync();
16
+ * if (info.ok) console.log(info.data.tokens.map(t => t.metadata?.symbol));
17
+ * ```
18
+ */
19
+
20
+ export * from "./config";
21
+ export * from "./types";
22
+ export * from "./utils";
23
+ export * from "./math";
24
+ export * from "./parsers";
25
+ export * from "./clients";
26
+ export * from "./idl";
27
+
28
+ // Explicit runtime re-exports keep CommonJS output statically discoverable for
29
+ // Vite/Rollup consumers that import named exports from the package root.
30
+ export {
31
+ getConfig,
32
+ programId,
33
+ CUBIC_POOL_SEED,
34
+ BPT_MINT_SEED,
35
+ STLD_HELPER_SEED,
36
+ TREASURY_SEED,
37
+ WEIGHT_SCALE,
38
+ MIN_WEIGHT,
39
+ MAX_WEIGHT,
40
+ MIN_TOKENS,
41
+ MAX_TOKENS,
42
+ BPT_DECIMALS,
43
+ SWAP_FEE_PRECISION,
44
+ PROTOCOL_FEE_PRECISION,
45
+ PERCENT_SCALE,
46
+ MAX_SWAP_FEE_RATE,
47
+ MAX_PROTOCOL_FEE_RATE,
48
+ MINIMUM_INITIAL_BPT,
49
+ SLIPPAGE_PRECISION,
50
+ MIN_SLIPPAGE_HBPS,
51
+ } from "./config";
52
+ export {
53
+ NETWORK_PROGRAMS,
54
+ DEFAULT_RPC_ENDPOINT,
55
+ DEFAULT_RPC_ENDPOINTS,
56
+ DEFAULT_RPC_TIMEOUT_MS,
57
+ } from "./config/networks";
58
+ export { KNOWN_TOKENS, resolveKnownToken } from "./config/tokens";
59
+ export { ok, err } from "./types/result";
60
+ export {
61
+ ONE,
62
+ mulDown,
63
+ mulUp,
64
+ divDown,
65
+ divUp,
66
+ complement,
67
+ weightToFp,
68
+ } from "./math/fixedPoint";
69
+ export { lnFp, expFp, powFp } from "./math/logExp";
70
+ export {
71
+ calcOutGivenIn,
72
+ calcBptOutGivenExactTokensIn,
73
+ calcTokensOutGivenBptIn,
74
+ calcSpotOut,
75
+ } from "./math/cubicMath";
76
+ export { validateWeights, calcSpotPrice } from "./math/weightedMath";
77
+ export {
78
+ capDepositAmountsToLpRatio,
79
+ computeAllocations,
80
+ computeTwoTokenOptimalAllocations,
81
+ } from "./math/singleToken";
82
+ export { applySlippage, applySwapFee, lpBalances, priceImpactHbps } from "./math/slippage";
83
+ export {
84
+ computeSelloffWindow,
85
+ projectSelloffWindow,
86
+ calcSurgeFeePct,
87
+ calcSurgeFeeAmount,
88
+ calcSegmentedSurgeFeeAmount,
89
+ SURGE_FEE_SEGMENTS,
90
+ } from "./math/maxSelloff";
91
+ export { RpcClient } from "./clients/RpcClient";
92
+ export { CofferBackendClient } from "./clients/CofferBackendClient";
93
+ export { CubicPoolClient } from "./clients/CubicPoolClient";
94
+ export { SingleTokenDepositClient } from "./clients/SingleTokenDepositClient";
95
+ export { PoolFactoryClient } from "./clients/PoolFactoryClient";
96
+ export { AdminClient } from "./clients/AdminClient";
97
+ export {
98
+ buildSwapIx,
99
+ buildSwapTx,
100
+ buildAddLiquidityIx,
101
+ buildAddLiquidityTx,
102
+ buildRemoveLiquidityIx,
103
+ buildRemoveLiquidityTx,
104
+ buildSingleTokenDepositIx,
105
+ buildSingleTokenDepositTx,
106
+ buildSingleTokenDepositTxs,
107
+ buildSingleTokenDepositAtaIxs,
108
+ buildInitializeConfigIx,
109
+ buildPoolInitializeConfigIx,
110
+ buildInitializeCubicPoolIx,
111
+ buildDeployPoolTx,
112
+ buildInitializePoolAltIx,
113
+ buildInitializePoolAltTx,
114
+ buildSetRangeManagerIx,
115
+ buildSetRangeManagerConfigIx,
116
+ buildRangeManagerUpdateIx,
117
+ deriveAltAddress,
118
+ STLD_MAX_TOKENS,
119
+ STLD_DEPOSIT_CU_LIMIT,
120
+ } from "./clients/tx-builders";
121
+ export { buildVersionedTx, compileBuiltTx } from "./clients/versioned";
122
+ export type { InitializePoolAltParams } from "./clients/tx-builders";
123
+ export { decodePoolAccount, POOL_DISCRIMINATOR_LEN, POOL_LEN, POOL_V4_LEN } from "./parsers/poolAccount";
124
+ export { toSdkError, describeProgramError } from "./utils/errors";
125
+ export { decodeMintAccount } from "./parsers/mintAccount";
126
+ export { parseCubicPoolEvents } from "./parsers/events";
127
+ export { BorshReader } from "./parsers/borsh";
128
+
129
+ export type {
130
+ CofferConfig,
131
+ CofferConfigOverrides,
132
+ ProgramIdKind,
133
+ Network,
134
+ NetworkPrograms,
135
+ TokenInfo,
136
+ } from "./config";
137
+ export type {
138
+ SdkResult,
139
+ SdkError,
140
+ SdkErrorCode,
141
+ PoolTokenInfo,
142
+ PoolInfo,
143
+ PoolSummary,
144
+ SwapParams,
145
+ SwapQuote,
146
+ AddLiquidityParams,
147
+ RemoveLiquidityParams,
148
+ SingleTokenDepositParams,
149
+ SingleTokenDepositQuote,
150
+ BuiltTx,
151
+ DeployPoolParams,
152
+ CubicPoolEvent,
153
+ PoolInitializedEvent,
154
+ SwapEvent,
155
+ LiquidityAddedEvent,
156
+ LiquidityRemovedEvent,
157
+ ProtocolFeesCollectedEvent,
158
+ PoolEnabledUpdatedEvent,
159
+ SwapsEnabledUpdatedEvent,
160
+ SingleTokenDepositEvent,
161
+ PoolStateLogEvent,
162
+ MaxSelloffWindowAdvancedEvent,
163
+ BannedExtensionsUpdatedEvent,
164
+ UnknownEvent,
165
+ TokenChange,
166
+ RangeManagerUpdateParams,
167
+ SetRangeManagerParams,
168
+ SetRangeManagerConfigParams,
169
+ } from "./types";
170
+ export type { CofferProgram } from "./utils/errors";
171
+ export type {
172
+ AllocationResult,
173
+ } from "./math/singleToken";
174
+ export type {
175
+ SelloffWindowInputs,
176
+ SelloffWindowStatus,
177
+ WindowProjection,
178
+ } from "./math/maxSelloff";
179
+ export type {
180
+ RawPoolAccount,
181
+ RawMintAccount,
182
+ } from "./parsers";
183
+ export type {
184
+ RpcClientParams,
185
+ CofferBackendClientParams,
186
+ StatsKind,
187
+ StatsWindow,
188
+ StatsSeriesPoint,
189
+ StatsSeries,
190
+ PriceMap,
191
+ LeaderboardEntry,
192
+ LeaderboardResponse,
193
+ LeaderboardUserStats,
194
+ XpAccrualHistoryEntry,
195
+ XpAccrualHistoryResponse,
196
+ EpochHistoryEntry,
197
+ LeaderboardEpochResponse,
198
+ CampaignStatusResponse,
199
+ CampaignInfoResponse,
200
+ CampaignPrizeTier,
201
+ CampaignRankResponse,
202
+ CampaignTopEntry,
203
+ CampaignTopResponse,
204
+ PortfolioChartMetric,
205
+ PortfolioChartRange,
206
+ PortfolioChartResponse,
207
+ PairChartRange,
208
+ TokenPairChartResponse,
209
+ PortfolioActivityType,
210
+ PortfolioActivityFilter,
211
+ ActivityTokenInfo,
212
+ PortfolioActivityItem,
213
+ PortfolioActivityResponse,
214
+ SortOrder,
215
+ PortfolioActivitySortField,
216
+ PortfolioHoldingsSortField,
217
+ PortfolioHoldingItem,
218
+ PortfolioHoldingsResponse,
219
+ PortfolioPositionsSortField,
220
+ PortfolioPositionItem,
221
+ PortfolioPositionsResponse,
222
+ NonceResponse,
223
+ TxChallengeResponse,
224
+ AuthTokens,
225
+ SwapRouteEntry,
226
+ SwapRouteResponse,
227
+ CubicPoolClientParams,
228
+ SingleTokenDepositClientParams,
229
+ PoolFactoryClientParams,
230
+ InitializeConfigParams,
231
+ } from "./clients";
232
+
233
+ export { buildContractInstruction } from "./clients/contract-instructions";
234
+ export { decodeContractAccount, decodeContractEvent, parseContractEvents } from "./parsers/contracts";
235
+ export type { ContractEvent } from "./parsers/contracts";
236
+ export type { ContractInstructionArgs, ContractInstructionAccounts } from "./clients/contract-instructions";
237
+ export type { ContractProgram, ContractInstructionMap, ContractAccountMap, ContractEventMap, ContractTypes } from "./types/contracts";
238
+ export { buildSetSwapFeeRateIx, buildSetMaxSelloffIx, buildInitiatePoolAdminTransferIx, buildAcceptPoolAdminTransferIx, buildCancelPoolAdminTransferIx, buildDisablePoolAdminIx, buildGetPoolInfoIx } from "./clients/tx-builders";
239
+ export type { SelloffParams, AddLiquidityQuote } from "./types/tx";
240
+ export { calculateSwapFee, calculateProtocolFee } from "./math/slippage";
241
+ export { checkAndAdvanceSelloff, rescaleSelloffWindow } from "./math/maxSelloff";
242
+ export type { SelloffState, SelloffResult } from "./math/maxSelloff";
243
+ export type { SurgeCurve } from "./math/surgeFee";
244
+ export { calculateInvariant } from "./math/weightedMath";
245
+
246
+ export { MintExtension, MAX_KNOWN_MINT_EXTENSION, HARD_UNSUPPORTED_MINT_EXTENSIONS, DEFAULT_BANNED_EXTENSIONS, mintExtensionName, parseMintExtensions, unsupportedMintExtensions, bannedMintExtensions, describeUnsupportedToken, assertTokensSupported } from "./utils/extensions";
247
+
248
+ // ── Legacy aliases (pre-rebrand identifiers) ────────────────────────────
249
+ // The package was renamed @cubee_ee/sdk → @coffer_so/sdk. These aliases
250
+ // keep old import names compiling so migration is just a package-name
251
+ // swap. New code should use the Coffer* names.
252
+ /** @deprecated Use `CofferBackendClient`. */
253
+ export { CofferBackendClient as CubeBackendClient } from "./clients/CofferBackendClient";
254
+ /** @deprecated Use `CofferConfig` / `CofferConfigOverrides`. */
255
+ export type {
256
+ CofferConfig as CubeConfig,
257
+ CofferConfigOverrides as CubeConfigOverrides,
258
+ } from "./config";
259
+ /** @deprecated Use `CofferProgram`. */
260
+ export type { CofferProgram as CubeProgram } from "./utils/errors";
261
+ /** @deprecated Use `CofferBackendClientParams`. */
262
+ export type { CofferBackendClientParams as CubeBackendClientParams } from "./clients";
@@ -0,0 +1,92 @@
1
+ import { complement, divDown, divUp, mulDown, ONE, weightToFp, assertU64, assertU128 } from "./fixedPoint";
2
+ import { powFp } from "./logExp";
3
+
4
+ /**
5
+ * Port of `CubicMath::calc_out_given_in` from
6
+ * `contracts/programs/cubic-pool/src/math/cubic_math.rs`.
7
+ *
8
+ * Formula: aO = bO * (1 - (bI / (bI + aI))^(wI / wO))
9
+ *
10
+ * Inputs are u64 raw amounts (bigint here to avoid overflow). Decimals
11
+ * cancel in the ratio bI/(bI+aI), so no scaling needed.
12
+ */
13
+ export function calcOutGivenIn(params: {
14
+ virtualBalanceIn: bigint;
15
+ weightInBps: bigint;
16
+ virtualBalanceOut: bigint;
17
+ weightOutBps: bigint;
18
+ amountIn: bigint;
19
+ actualBalanceOut: bigint;
20
+ }): bigint {
21
+ const { virtualBalanceIn, weightInBps, virtualBalanceOut, weightOutBps, amountIn, actualBalanceOut } =
22
+ params;
23
+ [virtualBalanceIn, weightInBps, virtualBalanceOut, weightOutBps, amountIn, actualBalanceOut].forEach((v) => assertU64(v));
24
+ const denom = assertU128(virtualBalanceIn + amountIn);
25
+ const base = divUp(virtualBalanceIn, denom);
26
+ const exp = divDown(weightToFp(weightInBps), weightToFp(weightOutBps));
27
+ let power = powFp(base, exp);
28
+ // Match Rust's +1 bias + clamp to ONE.
29
+ power = power + 1n;
30
+ if (power > ONE) power = ONE;
31
+ const comp = complement(power);
32
+ const out = mulDown(virtualBalanceOut, comp);
33
+ if (out > actualBalanceOut) {
34
+ throw new Error("cubicMath: amount out exceeds actual balance");
35
+ }
36
+ return assertU64(out);
37
+ }
38
+
39
+ /**
40
+ * Port of `CubicMath::calc_bpt_out_given_exact_tokens_in`.
41
+ * Proportional join: `bpt = total_supply * min(amount_i / actual_balance_i)`
42
+ * across tokens with `actual_balance_i > 0`.
43
+ */
44
+ export function calcBptOutGivenExactTokensIn(
45
+ actualBalances: bigint[],
46
+ amountsIn: bigint[],
47
+ bptTotalSupply: bigint
48
+ ): bigint {
49
+ if (actualBalances.length !== amountsIn.length) {
50
+ throw new Error("cubicMath: balances/amounts length mismatch");
51
+ }
52
+ assertU64(bptTotalSupply); actualBalances.forEach((v) => assertU64(v)); amountsIn.forEach((v) => assertU64(v));
53
+ let ratioMin: bigint | null = null;
54
+ for (let i = 0; i < actualBalances.length; i++) {
55
+ if (actualBalances[i] === 0n) continue;
56
+ const ratio = divDown(amountsIn[i], actualBalances[i]);
57
+ ratioMin = ratioMin === null || ratio < ratioMin ? ratio : ratioMin;
58
+ }
59
+ if (ratioMin === null) throw new Error("cubicMath: no live tokens");
60
+ return assertU64(assertU128(bptTotalSupply * ratioMin) / ONE);
61
+ }
62
+
63
+ /**
64
+ * Port of `CubicMath::calc_tokens_out_given_bpt_in`. Proportional exit.
65
+ */
66
+ export function calcTokensOutGivenBptIn(
67
+ actualBalances: bigint[],
68
+ bptAmount: bigint,
69
+ bptTotalSupply: bigint
70
+ ): bigint[] {
71
+ assertU64(bptAmount); assertU64(bptTotalSupply); actualBalances.forEach((v) => assertU64(v));
72
+ if (bptTotalSupply === 0n) throw new Error("cubicMath: zero total supply");
73
+ const ratio = divDown(bptAmount, bptTotalSupply);
74
+ return actualBalances.map((bal) => assertU64(mulDown(bal, ratio)));
75
+ }
76
+
77
+ /**
78
+ * Spot amount-out: aO = aI * (bO * wI) / (bI * wO). Always ≥
79
+ * `calcOutGivenIn` for the same inputs (curve slippage drags the real
80
+ * value below spot). Useful for UI "price impact" calculations.
81
+ */
82
+ export function calcSpotOut(params: {
83
+ virtualBalanceIn: bigint;
84
+ weightInBps: bigint;
85
+ virtualBalanceOut: bigint;
86
+ weightOutBps: bigint;
87
+ amountIn: bigint;
88
+ }): bigint {
89
+ const { virtualBalanceIn, weightInBps, virtualBalanceOut, weightOutBps, amountIn } = params;
90
+ if (virtualBalanceIn === 0n || weightOutBps === 0n) return 0n;
91
+ return (amountIn * virtualBalanceOut * weightInBps) / (virtualBalanceIn * weightOutBps);
92
+ }
@@ -0,0 +1,71 @@
1
+ /** Fixed-point primitives matching cubic-pool's checked u128 operations. */
2
+ export const ONE = 1000000000000000000n;
3
+ export const U64_MAX = (1n << 64n) - 1n;
4
+ export const U128_MAX = (1n << 128n) - 1n;
5
+ export const I128_MIN = -(1n << 127n);
6
+ export const I128_MAX = (1n << 127n) - 1n;
7
+ export function assertU64(value: bigint, label = "value"): bigint {
8
+ if (value < 0n || value > U64_MAX)
9
+ throw new Error(`${label}: outside u64`);
10
+ return value;
11
+ }
12
+ export function assertU128(value: bigint, label = "value"): bigint {
13
+ if (value < 0n || value > U128_MAX)
14
+ throw new Error(`${label}: outside u128`);
15
+ return value;
16
+ }
17
+ export function assertI128(value: bigint, label = "value"): bigint {
18
+ if (value < I128_MIN || value > I128_MAX)
19
+ throw new Error(`${label}: outside i128`);
20
+ return value;
21
+ }
22
+ export function assertInteger(value: number, min: number, max: number, label: string): number {
23
+ if (!Number.isSafeInteger(value) || value < min || value > max)
24
+ throw new Error(`${label}: invalid integer`);
25
+ return value;
26
+ }
27
+ /** Rust mul_div_down permits a 256-bit product, but a u128 quotient. */
28
+ export function mulDivDown(a: bigint, b: bigint, denominator: bigint): bigint {
29
+ assertU128(a);
30
+ assertU128(b);
31
+ assertU128(denominator);
32
+ if (denominator === 0n)
33
+ throw new Error("mulDivDown: divide by zero");
34
+ return assertU128(a * b / denominator);
35
+ }
36
+ export function mulDown(a: bigint, b: bigint): bigint {
37
+ assertU128(a);
38
+ assertU128(b);
39
+ return assertU128(a * b) / ONE;
40
+ }
41
+ export function mulUp(a: bigint, b: bigint): bigint {
42
+ assertU128(a);
43
+ assertU128(b);
44
+ const product = assertU128(a * b);
45
+ return product === 0n ? 0n : (product - 1n) / ONE + 1n;
46
+ }
47
+ export function divDown(a: bigint, b: bigint): bigint {
48
+ assertU128(a);
49
+ assertU128(b);
50
+ if (b === 0n)
51
+ throw new Error("fixedPoint.divDown: divide by zero");
52
+ return assertU128(a * ONE) / b;
53
+ }
54
+ export function divUp(a: bigint, b: bigint): bigint {
55
+ assertU128(a);
56
+ assertU128(b);
57
+ if (b === 0n)
58
+ throw new Error("fixedPoint.divUp: divide by zero");
59
+ const numerator = assertU128(a * ONE);
60
+ return numerator === 0n ? 0n : (numerator - 1n) / b + 1n;
61
+ }
62
+ export function complement(x: bigint): bigint {
63
+ assertU128(x);
64
+ if (x > ONE)
65
+ throw new Error("fixedPoint.complement: greater than ONE");
66
+ return ONE - x;
67
+ }
68
+ export function weightToFp(weightBps: bigint | number): bigint {
69
+ const w = typeof weightBps === "number" ? BigInt(assertInteger(weightBps, 0, 10000, "weight")) : assertU64(weightBps);
70
+ return w * ONE / 10000n;
71
+ }
@@ -0,0 +1,13 @@
1
+ export * from "./fixedPoint";
2
+ export * from "./logExp";
3
+ export * from "./cubicMath";
4
+ export * from "./weightedMath";
5
+ export * from "./singleToken";
6
+ export * from "./slippage";
7
+ export * from "./maxSelloff";
8
+ export * from "./lpLoss";
9
+ // NOTE: "./surgeFee" is deliberately NOT star-exported — its
10
+ // calcSurgeFeePct/calcSurgeFeeAmount would shadow the same-named maxSelloff
11
+ // exports (an ambiguous star re-export silently drops the name, breaking
12
+ // existing consumers). The quote engine imports it by path; only the
13
+ // SurgeCurve type is re-exported from the package root.
@@ -0,0 +1,61 @@
1
+ /** Exact integer port of cubic-pool log_exp_math.rs (audit-fixes-excluded-SF). */
2
+ import { ONE, assertI128, assertU128, mulDivDown } from "./fixedPoint";
3
+ export const MAX_NATURAL_EXPONENT = 46000000000000000000n;
4
+ export const MIN_NATURAL_EXPONENT = -41000000000000000000n;
5
+ const X = [32000000000000000000n, 16000000000000000000n, 8000000000000000000n, 4000000000000000000n, 2000000000000000000n, 1000000000000000000n, 500000000000000000n, 250000000000000000n, 125000000000000000n, 62500000000000000n];
6
+ const A = [78962960182680695161000000000000n, 8886110520507872636760000n, 2980957987041728274740n, 54598150033144239078n, 7389056098930650227n, 2718281828459045235n, 1648721270700128146n, 1284025416687741484n, 1133148453066826316n, 1064494458917859429n];
7
+ function lnPositive(a: bigint): bigint {
8
+ let sum = 0n;
9
+ for (let i = 0; i < X.length; i++)
10
+ if (a >= A[i]) {
11
+ a = mulDivDown(a, ONE, A[i]);
12
+ sum += X[i];
13
+ }
14
+ const z = mulDivDown(a - ONE, ONE, assertU128(a + ONE));
15
+ const zSq = assertI128(z * z) / ONE;
16
+ let num = z, seriesSum = z;
17
+ for (let k = 1n; k < 6n; k++) {
18
+ num = assertI128(num * zSq) / ONE;
19
+ seriesSum = assertI128(seriesSum + num / (2n * k + 1n));
20
+ }
21
+ return assertI128(sum + assertI128(seriesSum * 2n));
22
+ }
23
+ export function lnFp(a: bigint): bigint {
24
+ assertU128(a);
25
+ if (a === 0n)
26
+ throw new Error("logExp.ln: divide by zero");
27
+ return a < ONE ? -lnPositive(mulDivDown(ONE, ONE, a)) : lnPositive(a);
28
+ }
29
+ export function expFp(x: bigint): bigint {
30
+ assertI128(x);
31
+ if (x < MIN_NATURAL_EXPONENT || x > MAX_NATURAL_EXPONENT)
32
+ throw new Error("logExp.exp: exponent out of range");
33
+ if (x < 0n)
34
+ return mulDivDown(ONE, ONE, expFp(-x));
35
+ let product = ONE;
36
+ for (let i = 0; i < X.length; i++)
37
+ if (x >= X[i]) {
38
+ x -= X[i];
39
+ product = mulDivDown(product, A[i], ONE);
40
+ }
41
+ let sum = assertU128(ONE + x), term = x;
42
+ for (let n = 2n; n <= 12n; n++) {
43
+ term = mulDivDown(term, x, ONE) / n;
44
+ sum = assertU128(sum + term);
45
+ }
46
+ return mulDivDown(product, sum, ONE);
47
+ }
48
+ export function powFp(base: bigint, exponent: bigint): bigint {
49
+ assertU128(base);
50
+ assertU128(exponent);
51
+ if (exponent === 0n || base === ONE)
52
+ return ONE;
53
+ if (base === 0n)
54
+ return 0n;
55
+ const logarithm = lnFp(base);
56
+ // Rust casts u128 to i128 here. Valid pool weights are far below i128::MAX.
57
+ const y = BigInt.asIntN(128, exponent);
58
+ const whole = assertI128((logarithm / ONE) * y);
59
+ const fraction = assertI128((logarithm % ONE) * y) / ONE;
60
+ return expFp(assertI128(whole + fraction));
61
+ }
@@ -0,0 +1,160 @@
1
+ import {
2
+ PROTOCOL_FEE_PRECISION,
3
+ SWAP_FEE_PRECISION,
4
+ WEIGHT_SCALE,
5
+ } from "../config";
6
+
7
+ export interface PredictLpLossParams {
8
+ /** Normalized weights in bps (sum = WEIGHT_SCALE). */
9
+ weightsBps: number[];
10
+ virtualBalances: bigint[];
11
+ /** LP-accessible balances: actual − protocolFeesOwed. */
12
+ lpActualBalances: bigint[];
13
+ decimals: number[];
14
+ bptTotalSupply: bigint;
15
+ swapFeeRate: number;
16
+ protocolFeeRate: number;
17
+ tokenInIndex: number;
18
+ amountIn: bigint;
19
+ /** Per-token input allocations from the quote (sum = amountIn). */
20
+ allocations: bigint[];
21
+ /** Per-leg expected swap outputs (0 for the input token / sidelined). */
22
+ expectedOuts: bigint[];
23
+ /** Amounts passed to add_liquidity after proportional capping. */
24
+ depositedAmounts: bigint[];
25
+ /** Helper-held excess refunded to the user. */
26
+ refundAmounts: bigint[];
27
+ estimatedBpt: bigint;
28
+ /**
29
+ * External per-token prices in any common unit. When omitted or incomplete
30
+ * the pool-spot-implied prices (w_i / V_i) are used instead.
31
+ */
32
+ prices?: Array<number | null | undefined>;
33
+ }
34
+
35
+ const toWhole = (raw: bigint, decimals: number): number =>
36
+ Number(raw) / 10 ** decimals;
37
+
38
+ /**
39
+ * Predicted total value loss of the LP position minted by a single-token
40
+ * deposit, as a percent of the deposited value, measured AFTER arbitrageurs
41
+ * rebalance the pool back to external prices — the slippage-proof cost the
42
+ * depositor actually bears.
43
+ *
44
+ * Replays the quote's swap legs and join onto the pool state, then values
45
+ * the position at the closed-form zero-fee-arb equilibrium: with the
46
+ * invariant ∏V_i^w_i preserved, equilibrium virtuals are V'_i = λ·w_i/p_i
47
+ * and actual balances move by the same deltas. Validated against a full
48
+ * profit-maximizing arbitrage simulation of the contract math (±0.03 pp,
49
+ * slightly conservative). Float math — ample for percent-level output.
50
+ *
51
+ * Returns `null` when the pool is empty or inputs cannot price.
52
+ */
53
+ export function predictLpLoss(params: PredictLpLossParams): number | null {
54
+ const {
55
+ weightsBps,
56
+ virtualBalances,
57
+ lpActualBalances,
58
+ decimals,
59
+ bptTotalSupply,
60
+ swapFeeRate,
61
+ protocolFeeRate,
62
+ tokenInIndex,
63
+ amountIn,
64
+ allocations,
65
+ expectedOuts,
66
+ depositedAmounts,
67
+ refundAmounts,
68
+ estimatedBpt,
69
+ prices: externalPrices,
70
+ } = params;
71
+
72
+ const n = weightsBps.length;
73
+ if (
74
+ virtualBalances.length !== n ||
75
+ lpActualBalances.length !== n ||
76
+ decimals.length !== n
77
+ ) {
78
+ throw new Error("predictLpLoss: length mismatch");
79
+ }
80
+ if (tokenInIndex < 0 || tokenInIndex >= n) {
81
+ throw new Error("predictLpLoss: tokenInIndex out of range");
82
+ }
83
+
84
+ const supply = Number(bptTotalSupply);
85
+ const estBpt = Number(estimatedBpt);
86
+ const amountInWhole = toWhole(amountIn, decimals[tokenInIndex]);
87
+ if (supply <= 0 || estBpt <= 0 || amountInWhole <= 0) return null;
88
+
89
+ const weights: number[] = [];
90
+ const virtuals: number[] = [];
91
+ const actuals: number[] = [];
92
+ for (let i = 0; i < n; i++) {
93
+ weights.push(weightsBps[i] / WEIGHT_SCALE);
94
+ virtuals.push(toWhole(virtualBalances[i], decimals[i]));
95
+ actuals.push(toWhole(lpActualBalances[i], decimals[i]));
96
+ }
97
+
98
+ const externalComplete =
99
+ externalPrices !== undefined &&
100
+ externalPrices.length === n &&
101
+ externalPrices.every((p) => typeof p === "number" && p > 0);
102
+ const prices: number[] = [];
103
+ for (let i = 0; i < n; i++) {
104
+ const price = externalComplete
105
+ ? (externalPrices![i] as number)
106
+ : weights[i] / virtuals[i];
107
+ if (!Number.isFinite(price) || price <= 0) return null;
108
+ prices.push(price);
109
+ }
110
+
111
+ const feeRate = swapFeeRate / SWAP_FEE_PRECISION;
112
+ const protoRate = protocolFeeRate / PROTOCOL_FEE_PRECISION;
113
+ for (let i = 0; i < n; i++) {
114
+ if (i === tokenInIndex) continue;
115
+ const alloc = toWhole(allocations[i] ?? 0n, decimals[tokenInIndex]);
116
+ const out = toWhole(expectedOuts[i] ?? 0n, decimals[i]);
117
+ if (alloc <= 0 || out <= 0) continue;
118
+ const protoFee = alloc * feeRate * protoRate;
119
+ virtuals[tokenInIndex] += alloc - protoFee;
120
+ actuals[tokenInIndex] += alloc - protoFee;
121
+ virtuals[i] -= out;
122
+ actuals[i] -= out;
123
+ }
124
+
125
+ const mintRatio = estBpt / supply;
126
+ for (let i = 0; i < n; i++) {
127
+ actuals[i] += toWhole(depositedAmounts[i] ?? 0n, decimals[i]);
128
+ virtuals[i] *= 1 + mintRatio;
129
+ }
130
+
131
+ let logInvariant = 0;
132
+ let logTarget = 0;
133
+ for (let i = 0; i < n; i++) {
134
+ if (weights[i] <= 0 || virtuals[i] <= 0) return null;
135
+ logInvariant += weights[i] * Math.log(virtuals[i]);
136
+ logTarget += weights[i] * Math.log(weights[i] / prices[i]);
137
+ }
138
+ const lambda = Math.exp(logInvariant - logTarget);
139
+
140
+ let equilibriumPoolValue = 0;
141
+ for (let i = 0; i < n; i++) {
142
+ const equilibriumVirtual = (lambda * weights[i]) / prices[i];
143
+ const equilibriumActual = Math.max(
144
+ 0,
145
+ actuals[i] - (virtuals[i] - equilibriumVirtual)
146
+ );
147
+ equilibriumPoolValue += equilibriumActual * prices[i];
148
+ }
149
+
150
+ const lpValue = (mintRatio / (1 + mintRatio)) * equilibriumPoolValue;
151
+ let refundValue = 0;
152
+ for (let i = 0; i < n; i++) {
153
+ refundValue += toWhole(refundAmounts[i] ?? 0n, decimals[i]) * prices[i];
154
+ }
155
+ const depositValue = amountInWhole * prices[tokenInIndex];
156
+ if (depositValue <= 0) return null;
157
+
158
+ const loss = 1 - (lpValue + refundValue) / depositValue;
159
+ return Math.min(100, Math.max(0, loss * 100));
160
+ }