@alephium/powfi-sdk 0.0.1-rc.2 → 0.0.1-rc.21

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 (60) hide show
  1. package/README.md +97 -1
  2. package/clmm/artifacts/BitmapWord.ral.json +1 -1
  3. package/clmm/artifacts/BitmapWordDeployer.ral.json +1 -1
  4. package/clmm/artifacts/CreateConfig.ral.json +1 -1
  5. package/clmm/artifacts/CreateLiquidPool.ral.json +1 -1
  6. package/clmm/artifacts/DexAccount.ral.json +1 -1
  7. package/clmm/artifacts/LiquidityAmountsTest.ral.json +1 -1
  8. package/clmm/artifacts/LiquidityManagmentTest.ral.json +1 -1
  9. package/clmm/artifacts/Pool.ral.json +14 -5
  10. package/clmm/artifacts/PoolConfig.ral.json +1 -1
  11. package/clmm/artifacts/PoolFactory.ral.json +1 -1
  12. package/clmm/artifacts/PoolRouterDemo.ral.json +2 -2
  13. package/clmm/artifacts/PoolUser.ral.json +1 -1
  14. package/clmm/artifacts/Position.ral.json +18 -4
  15. package/clmm/artifacts/PositionManager.ral.json +1 -1
  16. package/clmm/artifacts/SwapWithoutAccount.ral.json +2 -2
  17. package/clmm/artifacts/TestToken.ral.json +1 -1
  18. package/clmm/artifacts/Tick.ral.json +1 -1
  19. package/clmm/artifacts/TickBitmapTest.ral.json +1 -1
  20. package/clmm/artifacts/ts/Pool.ts +14 -2
  21. package/clmm/artifacts/ts/Position.ts +37 -3
  22. package/cpmm/artifacts/scripts/CreatePairAndAddLiquidity.ral.json +6 -3
  23. package/cpmm/artifacts/ts/scripts.ts +1 -0
  24. package/lib/index.d.mts +242 -119
  25. package/lib/index.d.ts +242 -119
  26. package/lib/index.js +627 -329
  27. package/lib/index.js.map +1 -1
  28. package/lib/index.mjs +628 -329
  29. package/lib/index.mjs.map +1 -1
  30. package/package.json +9 -8
  31. package/src/clmm/clmm.ts +70 -47
  32. package/src/clmm/liquidity.ts +1 -1
  33. package/src/clmm/pool.ts +15 -17
  34. package/src/clmm/tick.ts +21 -33
  35. package/src/clmm/types.ts +12 -12
  36. package/src/common/error.ts +7 -7
  37. package/src/common/types.ts +1 -1
  38. package/src/cpmm/cpmm.ts +135 -103
  39. package/src/cpmm/types.ts +48 -42
  40. package/src/index.ts +1 -1
  41. package/src/moduleBase.ts +3 -3
  42. package/src/{zeta.ts → powfi.ts} +5 -5
  43. package/src/staking/staking.ts +31 -24
  44. package/src/token/token.ts +2 -2
  45. package/staking/artifacts/AlphUnstakeVault.ral.json +13 -3
  46. package/staking/artifacts/XAlphStakeVault.ral.json +1 -1
  47. package/staking/artifacts/XAlphToken.ral.json +139 -6
  48. package/staking/artifacts/XAlphUnlockAndStartUnstake.ral.json +2 -2
  49. package/staking/artifacts/examples/GovernanceDemo.ral.json +1 -1
  50. package/staking/artifacts/examples/RewardSharingVault.ral.json +1 -1
  51. package/staking/artifacts/ts/AlphUnstakeVault.ts +40 -1
  52. package/staking/artifacts/ts/XAlphToken.ts +209 -8
  53. package/staking/artifacts/ts/scripts.ts +0 -10
  54. package/staking/artifacts/utils/FullMathTest.ral.json +1 -1
  55. package/staking/artifacts/utils/TestDynamicArrayByteVec32.ral.json +1 -1
  56. package/staking/artifacts/utils/TestDynamicSortedArrayForU256.ral.json +1 -1
  57. package/staking/artifacts/utils/TestMerkleProof.ral.json +1 -1
  58. package/staking/deployments/.deployments.devnet.json +45 -44
  59. package/staking/deployments/.deployments.testnet.json +23 -23
  60. package/staking/artifacts/AlphStakeAndLock.ral.json +0 -31
package/src/cpmm/cpmm.ts CHANGED
@@ -15,9 +15,10 @@ import {
15
15
  RemoveLiquidity,
16
16
  CreatePair,
17
17
  CreatePairAndAddLiquidity,
18
+ TokenPairFactory,
18
19
  } from 'cpmm/artifacts/ts';
19
20
  import { loadDeployments } from 'cpmm/artifacts/ts/deployments';
20
- import type { CpmmPoolContractState } from './types';
21
+ import type { TokenInfo } from '@alephium/token-list';
21
22
  import { sortTokens } from '../common/utils';
22
23
  import { MAX_PRICE_IMPACT } from './constants';
23
24
  import {
@@ -26,19 +27,20 @@ import {
26
27
  PoolNotFoundError,
27
28
  } from '../common/error';
28
29
  import type {
29
- SwapParams,
30
- SwapDetails,
31
- AddLiquidityParams,
32
- AddLiquidityDetails,
33
- RemoveLiquidityParams,
34
- RemoveLiquidityDetails,
35
- ClaimableAmounts,
36
- CreatePoolParams,
37
- ComputeSwapParams,
38
- ComputeLiquidityParams,
30
+ CpmmAddLiquidityQuote,
31
+ CpmmAddLiquidityQuoteParams,
32
+ CpmmAddLiquidityRequest,
33
+ CpmmClaimableAmounts,
39
34
  CpmmConfig,
35
+ CpmmCreatePoolRequest,
36
+ CpmmPoolContractState,
37
+ CpmmRemoveLiquidityQuote,
38
+ CpmmRemoveLiquidityRequest,
39
+ CpmmSwapQuote,
40
+ CpmmSwapQuoteParams,
41
+ CpmmSwapRequest,
40
42
  } from './types';
41
- import type { Zeta } from '../zeta';
43
+ import type { Powfi } from '../powfi';
42
44
  import ModuleBase from '../moduleBase';
43
45
  import BigNumber from 'bignumber.js';
44
46
  import { MathUtil } from '../common/math';
@@ -49,7 +51,7 @@ import { InsufficientLiquidityError } from '../common/error';
49
51
  export class CpmmModule extends ModuleBase {
50
52
  private config: CpmmConfig;
51
53
 
52
- constructor(scope: Zeta) {
54
+ constructor(scope: Powfi) {
53
55
  super({ scope, moduleName: 'CpmmModule' });
54
56
 
55
57
  this.config = this.getCpmmConfig();
@@ -108,19 +110,22 @@ export class CpmmModule extends ModuleBase {
108
110
  });
109
111
  }
110
112
 
111
- async swap(params: SwapParams, balances?: Map<string, bigint>): Promise<ExecuteScriptResult> {
113
+ async swap(
114
+ params: CpmmSwapRequest,
115
+ balances?: Map<string, bigint>,
116
+ ): Promise<ExecuteScriptResult> {
112
117
  if (!this.scope.signer) {
113
118
  throw new Error('Signer is required for swap operation');
114
119
  }
115
120
 
116
- const poolState = await this.getPoolState(params.tokenIn.id, params.tokenOut.id);
121
+ const poolState = await this.getPoolState(params.tokenInId, params.tokenOutId);
117
122
  const swapDetails = CpmmModule.computeSwapAmount({
118
123
  state: poolState,
119
- tokenIn: params.tokenIn,
120
- tokenOut: params.tokenOut,
124
+ tokenInId: params.tokenInId,
125
+ tokenOutId: params.tokenOutId,
121
126
  amountIn: params.amountIn,
122
127
  amountOut: params.amountOut,
123
- slippage: params.slippage,
128
+ slippageBps: params.slippageBps,
124
129
  });
125
130
 
126
131
  if (swapDetails.priceImpact >= MAX_PRICE_IMPACT) {
@@ -133,13 +138,13 @@ export class CpmmModule extends ModuleBase {
133
138
  throw new InsufficientBalanceError(
134
139
  swapDetails.tokenInInfo.symbol,
135
140
  prettifyTokenAmount(swapDetails.tokenInAmount, swapDetails.tokenInInfo.decimals) ??
136
- `${swapDetails.tokenInAmount}`,
141
+ `${swapDetails.tokenInAmount}`,
137
142
  prettifyTokenAmount(available, swapDetails.tokenInInfo.decimals) ?? `${available}`,
138
143
  );
139
144
  }
140
145
  }
141
146
 
142
- const ttl = params.ttl ?? 60;
147
+ const ttlMinutes = params.ttlMinutes ?? 60;
143
148
 
144
149
  if (swapDetails.swapType === 'ExactIn') {
145
150
  let attoAlphAmount = this.getExtraAlphAmount(
@@ -164,7 +169,7 @@ export class CpmmModule extends ModuleBase {
164
169
  tokenInId: swapDetails.tokenInInfo.id,
165
170
  amountIn: swapDetails.tokenInAmount,
166
171
  amountOutMin: swapDetails.minimalTokenOutAmount!,
167
- deadline: deadline(ttl),
172
+ deadline: deadline(ttlMinutes),
168
173
  },
169
174
  attoAlphAmount,
170
175
  tokens,
@@ -192,7 +197,7 @@ export class CpmmModule extends ModuleBase {
192
197
  tokenInId: swapDetails.tokenInInfo.id,
193
198
  amountInMax: swapDetails.maximalTokenInAmount!,
194
199
  amountOut: swapDetails.tokenOutAmount,
195
- deadline: deadline(ttl),
200
+ deadline: deadline(ttlMinutes),
196
201
  },
197
202
  attoAlphAmount,
198
203
  tokens,
@@ -202,62 +207,73 @@ export class CpmmModule extends ModuleBase {
202
207
  }
203
208
 
204
209
  async addLiquidity(
205
- params: AddLiquidityParams,
210
+ params: CpmmAddLiquidityRequest,
206
211
  balances?: Map<string, bigint>,
207
212
  ): Promise<ExecuteScriptResult> {
208
213
  if (!this.scope.signer) {
209
214
  throw new Error('Signer is required for addLiquidity operation');
210
215
  }
211
216
 
212
- const { cpmmPoolState, tokenA, tokenB, amountA, amountB, slippage, sender, ttl = 60 } = params;
217
+ const {
218
+ poolState,
219
+ tokenAId,
220
+ tokenBId,
221
+ amountA,
222
+ amountB,
223
+ slippageBps,
224
+ sender,
225
+ ttlMinutes = 60,
226
+ } = params;
227
+ const tokenAInfo = CpmmModule.getTokenInfoFromPoolState(poolState, tokenAId, 'tokenAId');
228
+ const tokenBInfo = CpmmModule.getTokenInfoFromPoolState(poolState, tokenBId, 'tokenBId');
213
229
 
214
230
  if (amountA === 0n || amountB === 0n) {
215
231
  throw new Error('The input amount must be greater than 0');
216
232
  }
217
233
 
218
234
  if (balances) {
219
- const tokenAAvailable = balances.get(tokenA.id) ?? 0n;
235
+ const tokenAAvailable = balances.get(tokenAInfo.id) ?? 0n;
220
236
  if (tokenAAvailable < amountA) {
221
237
  throw new InsufficientBalanceError(
222
- tokenA.symbol,
223
- prettifyTokenAmount(amountA, tokenA.decimals) ?? `${amountA}`,
224
- prettifyTokenAmount(tokenAAvailable, tokenA.decimals) ?? `${tokenAAvailable}`,
238
+ tokenAInfo.symbol,
239
+ prettifyTokenAmount(amountA, tokenAInfo.decimals) ?? `${amountA}`,
240
+ prettifyTokenAmount(tokenAAvailable, tokenAInfo.decimals) ?? `${tokenAAvailable}`,
225
241
  );
226
242
  }
227
243
 
228
- const tokenBAvailable = balances.get(tokenB.id) ?? 0n;
244
+ const tokenBAvailable = balances.get(tokenBInfo.id) ?? 0n;
229
245
  if (tokenBAvailable < amountB) {
230
246
  throw new InsufficientBalanceError(
231
- tokenB.symbol,
232
- prettifyTokenAmount(amountB, tokenB.decimals) ?? `${amountB}`,
233
- prettifyTokenAmount(tokenBAvailable, tokenB.decimals) ?? `${tokenBAvailable}`,
247
+ tokenBInfo.symbol,
248
+ prettifyTokenAmount(amountB, tokenBInfo.decimals) ?? `${amountB}`,
249
+ prettifyTokenAmount(tokenBAvailable, tokenBInfo.decimals) ?? `${tokenBAvailable}`,
234
250
  );
235
251
  }
236
252
  }
237
253
 
238
- const isInitial = cpmmPoolState.reserve0 === 0n && cpmmPoolState.reserve1 === 0n;
239
- const amountAMin = isInitial ? amountA : CpmmModule.minimalAmount(amountA, slippage);
240
- const amountBMin = isInitial ? amountB : CpmmModule.minimalAmount(amountB, slippage);
254
+ const isInitial = poolState.reserve0 === 0n && poolState.reserve1 === 0n;
255
+ const amountAMin = isInitial ? amountA : CpmmModule.minimalAmount(amountA, slippageBps);
256
+ const amountBMin = isInitial ? amountB : CpmmModule.minimalAmount(amountB, slippageBps);
241
257
 
242
258
  const [amount0Desired, amount1Desired, amount0Min, amount1Min] =
243
- tokenA.id === cpmmPoolState.token0Info.id
259
+ tokenAId === poolState.token0Info.id
244
260
  ? [amountA, amountB, amountAMin, amountBMin]
245
261
  : [amountB, amountA, amountBMin, amountAMin];
246
262
 
247
263
  // Calculate ALPH amounts properly
248
- const extraAlph = this.getExtraAlphAmount(tokenA.id, tokenB.id);
264
+ const extraAlph = this.getExtraAlphAmount(tokenAId, tokenBId);
249
265
  let attoAlphAmount = extraAlph + DUST_AMOUNT;
250
266
  const tokens: Array<{ id: string; amount: bigint }> = [];
251
267
 
252
268
  // Handle ALPH token properly - don't double count it
253
- if (tokenA.id === ALPH_TOKEN_ID) {
269
+ if (tokenAId === ALPH_TOKEN_ID) {
254
270
  attoAlphAmount += amountA;
255
- tokens.push({ id: tokenB.id, amount: amountB });
256
- } else if (tokenB.id === ALPH_TOKEN_ID) {
271
+ tokens.push({ id: tokenBId, amount: amountB });
272
+ } else if (tokenBId === ALPH_TOKEN_ID) {
257
273
  attoAlphAmount += amountB;
258
- tokens.push({ id: tokenA.id, amount: amountA });
274
+ tokens.push({ id: tokenAId, amount: amountA });
259
275
  } else {
260
- tokens.push({ id: tokenA.id, amount: amountA }, { id: tokenB.id, amount: amountB });
276
+ tokens.push({ id: tokenAId, amount: amountA }, { id: tokenBId, amount: amountB });
261
277
  }
262
278
 
263
279
  const result = await AddLiquidity.execute({
@@ -265,12 +281,12 @@ export class CpmmModule extends ModuleBase {
265
281
  initialFields: {
266
282
  sender,
267
283
  router: this.config.routerId,
268
- pair: cpmmPoolState.poolId,
284
+ pair: poolState.poolId,
269
285
  amount0Desired,
270
286
  amount1Desired,
271
287
  amount0Min,
272
288
  amount1Min,
273
- deadline: deadline(ttl),
289
+ deadline: deadline(ttlMinutes),
274
290
  },
275
291
  attoAlphAmount,
276
292
  tokens,
@@ -278,32 +294,39 @@ export class CpmmModule extends ModuleBase {
278
294
  return result;
279
295
  }
280
296
 
281
- async removeLiquidity(params: RemoveLiquidityParams): Promise<ExecuteScriptResult> {
297
+ async removeLiquidity(params: CpmmRemoveLiquidityRequest): Promise<ExecuteScriptResult> {
282
298
  if (!this.scope.signer) {
283
299
  throw new Error('Signer is required for removeLiquidity operation');
284
300
  }
285
301
 
286
- const { state, liquidity, totalLiquidityAmount, slippage, sender, ttl = 60 } = params;
287
- const ownedLiquidity = totalLiquidityAmount ?? state.totalSupply;
288
- const details = CpmmModule.computeRemoveLiquidityAmounts(state, ownedLiquidity, liquidity);
302
+ const {
303
+ poolState,
304
+ liquidity,
305
+ totalLiquidityAmount,
306
+ slippageBps,
307
+ sender,
308
+ ttlMinutes = 60,
309
+ } = params;
310
+ const ownedLiquidity = totalLiquidityAmount ?? poolState.totalSupply;
311
+ const details = CpmmModule.computeRemoveLiquidityAmounts(poolState, ownedLiquidity, liquidity);
289
312
 
290
- const amount0Min = CpmmModule.minimalAmount(details.amount0, slippage);
291
- const amount1Min = CpmmModule.minimalAmount(details.amount1, slippage);
313
+ const amount0Min = CpmmModule.minimalAmount(details.amount0, slippageBps);
314
+ const amount1Min = CpmmModule.minimalAmount(details.amount1, slippageBps);
292
315
 
293
316
  const result = await RemoveLiquidity.execute({
294
317
  signer: this.scope.signer,
295
318
  initialFields: {
296
319
  sender,
297
320
  router: this.config.routerId,
298
- pairId: state.poolId,
321
+ pairId: poolState.poolId,
299
322
  liquidity,
300
323
  amount0Min,
301
324
  amount1Min,
302
- deadline: deadline(ttl),
325
+ deadline: deadline(ttlMinutes),
303
326
  },
304
327
  attoAlphAmount:
305
- this.getExtraAlphAmount(state.token0Info.id, state.token1Info.id) + DUST_AMOUNT,
306
- tokens: [{ id: state.poolId, amount: liquidity }],
328
+ this.getExtraAlphAmount(poolState.token0Info.id, poolState.token1Info.id) + DUST_AMOUNT,
329
+ tokens: [{ id: poolState.poolId, amount: liquidity }],
307
330
  });
308
331
  return result;
309
332
  }
@@ -312,7 +335,7 @@ export class CpmmModule extends ModuleBase {
312
335
  tokenAId: string,
313
336
  tokenBId: string,
314
337
  liquidityBalance: bigint,
315
- ): Promise<ClaimableAmounts> {
338
+ ): Promise<CpmmClaimableAmounts> {
316
339
  const state = await this.getPoolState(tokenAId, tokenBId);
317
340
  const details = CpmmModule.computeClaimableAmounts(state, liquidityBalance);
318
341
  return {
@@ -323,18 +346,23 @@ export class CpmmModule extends ModuleBase {
323
346
  };
324
347
  }
325
348
 
326
- async createPool(params: CreatePoolParams): Promise<ExecuteScriptResult & { poolId: string }> {
349
+ async createPool(
350
+ params: CpmmCreatePoolRequest,
351
+ ): Promise<ExecuteScriptResult & { poolId: string }> {
327
352
  if (!this.scope.signer) {
328
353
  throw new Error('Signer is required for createPool operation');
329
354
  }
330
355
 
331
- const { tokenA, tokenB, sender, tokenAAmount, tokenBAmount } = params;
332
- const poolId = this.getPoolId(tokenA.id, tokenB.id);
356
+ const { tokenAId, tokenBId, sender, initialLiquidity } = params;
357
+ const poolId = this.getPoolId(tokenAId, tokenBId);
333
358
 
334
- if (tokenAAmount !== undefined && tokenBAmount !== undefined) {
335
- const [token0Id, token1Id] = sortTokens(tokenA.id, tokenB.id);
359
+ if (initialLiquidity) {
360
+ const { tokenAAmount, tokenBAmount } = initialLiquidity;
361
+ const [token0Id, token1Id] = sortTokens(tokenAId, tokenBId);
336
362
  const [amount0, amount1] =
337
- token0Id === tokenA.id ? [tokenAAmount, tokenBAmount] : [tokenBAmount, tokenAAmount];
363
+ token0Id === tokenAId ? [tokenAAmount, tokenBAmount] : [tokenBAmount, tokenAAmount];
364
+ const state = await TokenPairFactory.at(addressFromContractId(this.config.factoryId)).fetchState();
365
+
338
366
  const result = await CreatePairAndAddLiquidity.execute({
339
367
  signer: this.scope.signer,
340
368
  initialFields: {
@@ -345,8 +373,9 @@ export class CpmmModule extends ModuleBase {
345
373
  token1Id,
346
374
  amount0,
347
375
  amount1,
376
+ dexAccount: state.fields.dexAccount0
348
377
  },
349
- attoAlphAmount: ONE_ALPH + this.getExtraAlphAmount(tokenA.id, tokenB.id),
378
+ attoAlphAmount: ONE_ALPH + this.getExtraAlphAmount(tokenAId, tokenBId),
350
379
  tokens: [
351
380
  { id: token0Id, amount: amount0 },
352
381
  { id: token1Id, amount: amount1 },
@@ -361,13 +390,13 @@ export class CpmmModule extends ModuleBase {
361
390
  payer: sender,
362
391
  factory: this.config.factoryId,
363
392
  alphAmount: ONE_ALPH,
364
- tokenAId: tokenA.id,
365
- tokenBId: tokenB.id,
393
+ tokenAId,
394
+ tokenBId,
366
395
  },
367
- attoAlphAmount: ONE_ALPH + this.getExtraAlphAmount(tokenA.id, tokenB.id),
396
+ attoAlphAmount: ONE_ALPH + this.getExtraAlphAmount(tokenAId, tokenBId),
368
397
  tokens: [
369
- { id: tokenA.id, amount: 1n },
370
- { id: tokenB.id, amount: 1n },
398
+ { id: tokenAId, amount: 1n },
399
+ { id: tokenBId, amount: 1n },
371
400
  ],
372
401
  });
373
402
  return { ...result, poolId };
@@ -387,8 +416,10 @@ export class CpmmModule extends ModuleBase {
387
416
  }
388
417
  }
389
418
 
390
- static computeSwapAmount(params: ComputeSwapParams): SwapDetails {
391
- const { state, tokenIn, tokenOut, amountIn, amountOut, slippage } = params;
419
+ static computeSwapAmount(params: CpmmSwapQuoteParams): CpmmSwapQuote {
420
+ const { state, tokenInId, tokenOutId, amountIn, amountOut, slippageBps } = params;
421
+ const tokenInInfo = this.getTokenInfoFromPoolState(state, tokenInId, 'tokenInId');
422
+ const tokenOutInfo = this.getTokenInfoFromPoolState(state, tokenOutId, 'tokenOutId');
392
423
 
393
424
  let swapType: 'ExactIn' | 'ExactOut';
394
425
  let tokenInAmount: bigint;
@@ -397,10 +428,10 @@ export class CpmmModule extends ModuleBase {
397
428
  if (amountIn !== undefined) {
398
429
  swapType = 'ExactIn';
399
430
  tokenInAmount = amountIn;
400
- tokenOutAmount = CpmmModule.getAmountOut(state, tokenIn.id, amountIn);
431
+ tokenOutAmount = CpmmModule.getAmountOut(state, tokenInInfo.id, amountIn);
401
432
  } else if (amountOut !== undefined) {
402
433
  swapType = 'ExactOut';
403
- tokenInAmount = CpmmModule.getAmountIn(state, tokenOut.id, amountOut);
434
+ tokenInAmount = CpmmModule.getAmountIn(state, tokenOutInfo.id, amountOut);
404
435
  tokenOutAmount = amountOut;
405
436
  } else {
406
437
  throw new Error('Either amountIn or amountOut must be specified');
@@ -409,7 +440,7 @@ export class CpmmModule extends ModuleBase {
409
440
  const priceImpact = this.calcPriceImpact(
410
441
  state.reserve0,
411
442
  state.reserve1,
412
- tokenIn.id,
443
+ tokenInInfo.id,
413
444
  state.token0Info.id,
414
445
  tokenInAmount,
415
446
  tokenOutAmount,
@@ -418,45 +449,47 @@ export class CpmmModule extends ModuleBase {
418
449
  return {
419
450
  swapType,
420
451
  state,
421
- tokenInInfo: tokenIn,
422
- tokenOutInfo: tokenOut,
452
+ tokenInInfo,
453
+ tokenOutInfo,
423
454
  tokenInAmount,
424
455
  tokenOutAmount,
425
456
  priceImpact,
426
457
  minimalTokenOutAmount:
427
- swapType === 'ExactIn' ? this.minimalAmount(tokenOutAmount, slippage) : undefined,
458
+ swapType === 'ExactIn' ? this.minimalAmount(tokenOutAmount, slippageBps) : undefined,
428
459
  maximalTokenInAmount:
429
- swapType === 'ExactOut' ? this.maximalAmount(tokenInAmount, slippage) : undefined,
460
+ swapType === 'ExactOut' ? this.maximalAmount(tokenInAmount, slippageBps) : undefined,
430
461
  };
431
462
  }
432
463
 
433
- static computeLiquidityAmounts(params: ComputeLiquidityParams): AddLiquidityDetails {
434
- const { state, tokenA, tokenB, amountA, amountB, inputType = 'TokenA' } = params;
464
+ static computeLiquidityAmounts(
465
+ params: CpmmAddLiquidityQuoteParams,
466
+ ): CpmmAddLiquidityQuote {
467
+ const { poolState, tokenAId, tokenBId, amountA, amountB, inputType = 'TokenA' } = params;
435
468
 
436
- if (!state) {
469
+ if (!poolState) {
437
470
  // Initial liquidity
438
- if (!amountA || !amountB) {
471
+ if (amountA === undefined || amountB === undefined) {
439
472
  throw new Error('Both amountA and amountB are required for initial liquidity');
440
473
  }
441
- return this.getInitLiquidityDetails(tokenA.id, tokenB.id, amountA, amountB);
474
+ return this.getInitLiquidityDetails(tokenAId, tokenBId, amountA, amountB);
442
475
  }
443
476
 
444
477
  // Adding to existing pool
445
- const inputTokenId = inputType === 'TokenA' ? tokenA.id : tokenB.id;
478
+ const inputTokenId = inputType === 'TokenA' ? tokenAId : tokenBId;
446
479
  const inputAmount = inputType === 'TokenA' ? amountA : amountB;
447
480
 
448
- if (!inputAmount) {
481
+ if (inputAmount === undefined) {
449
482
  throw new Error(`Amount for ${inputType} is required`);
450
483
  }
451
484
 
452
- return this.getLiquidityDetails(state, inputTokenId, inputAmount, inputType);
485
+ return this.getLiquidityDetails(poolState, inputTokenId, inputAmount, inputType);
453
486
  }
454
487
 
455
488
  static computeRemoveLiquidityAmounts(
456
489
  state: CpmmPoolContractState,
457
490
  totalLiquidity: bigint,
458
491
  liquidityToRemove: bigint,
459
- ): RemoveLiquidityDetails {
492
+ ): CpmmRemoveLiquidityQuote {
460
493
  if (liquidityToRemove > totalLiquidity) {
461
494
  throw new Error('Liquidity exceeds total liquidity amount');
462
495
  }
@@ -483,7 +516,7 @@ export class CpmmModule extends ModuleBase {
483
516
  static computeClaimableAmounts(
484
517
  state: CpmmPoolContractState,
485
518
  liquidityBalance: bigint,
486
- ): RemoveLiquidityDetails {
519
+ ): CpmmRemoveLiquidityQuote {
487
520
  return this.computeRemoveLiquidityAmounts(state, liquidityBalance, liquidityBalance);
488
521
  }
489
522
 
@@ -527,15 +560,7 @@ export class CpmmModule extends ModuleBase {
527
560
  inputTokenId: string,
528
561
  inputAmount: bigint,
529
562
  inputType: 'TokenA' | 'TokenB', // First or second token in the token input box
530
- ): {
531
- state: CpmmPoolContractState;
532
- tokenAId: string;
533
- tokenBId: string;
534
- amountA: bigint;
535
- amountB: bigint;
536
- shareAmount: bigint;
537
- sharePercentage: number;
538
- } {
563
+ ): CpmmAddLiquidityQuote {
539
564
  const isInputToken0 = inputTokenId === state.token0Info.id;
540
565
  const [reserveA, reserveB] = isInputToken0
541
566
  ? [state.reserve0, state.reserve1]
@@ -588,14 +613,7 @@ export class CpmmModule extends ModuleBase {
588
613
  tokenBId: string,
589
614
  amountA: bigint,
590
615
  amountB: bigint,
591
- ): {
592
- tokenAId: string;
593
- tokenBId: string;
594
- amountA: bigint;
595
- amountB: bigint;
596
- shareAmount: bigint;
597
- sharePercentage: number;
598
- } {
616
+ ): CpmmAddLiquidityQuote {
599
617
  const liquidity = MathUtil.sqrt(amountA * amountB);
600
618
  if (liquidity <= MINIMUM_LIQUIDITY) {
601
619
  throw new InsufficientLiquidityError('Insufficient initial liquidity');
@@ -610,6 +628,20 @@ export class CpmmModule extends ModuleBase {
610
628
  };
611
629
  }
612
630
 
631
+ private static getTokenInfoFromPoolState(
632
+ state: CpmmPoolContractState,
633
+ tokenId: string,
634
+ tokenLabel: string,
635
+ ): TokenInfo {
636
+ if (state.token0Info.id === tokenId) {
637
+ return state.token0Info;
638
+ }
639
+ if (state.token1Info.id === tokenId) {
640
+ return state.token1Info;
641
+ }
642
+ throw new Error(`Unknown ${tokenLabel} ${tokenId} for pool ${state.poolId}`);
643
+ }
644
+
613
645
  private static _getAmountOut(amountIn: bigint, reserveIn: bigint, reserveOut: bigint): bigint {
614
646
  const amountInExcludeFee = 997n * amountIn;
615
647
  const numerator = amountInExcludeFee * reserveOut;
package/src/cpmm/types.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import type { TokenInfo } from '@alephium/token-list';
2
2
 
3
+ export type CpmmTokenId = string;
4
+ export type CpmmSlippageBps = bigint;
5
+ export type CpmmInputType = 'TokenA' | 'TokenB';
6
+
3
7
  export interface CpmmConfig {
4
8
  groupIndex: number;
5
9
  factoryId: string;
@@ -17,17 +21,26 @@ export interface CpmmPoolContractState {
17
21
  dexAccount: string;
18
22
  }
19
23
 
20
- export interface SwapParams {
21
- tokenIn: TokenInfo;
22
- tokenOut: TokenInfo;
24
+ export interface CpmmSwapRequest {
25
+ tokenInId: CpmmTokenId;
26
+ tokenOutId: CpmmTokenId;
23
27
  amountIn?: bigint;
24
28
  amountOut?: bigint;
25
- slippage: bigint; // bps
29
+ slippageBps: CpmmSlippageBps;
26
30
  sender: string;
27
- ttl?: number; // Time to live in minutes, default 60
31
+ ttlMinutes?: number; // defaults to 60
32
+ }
33
+
34
+ export interface CpmmSwapQuoteParams {
35
+ state: CpmmPoolContractState;
36
+ tokenInId: CpmmTokenId;
37
+ tokenOutId: CpmmTokenId;
38
+ amountIn?: bigint;
39
+ amountOut?: bigint;
40
+ slippageBps: CpmmSlippageBps;
28
41
  }
29
42
 
30
- export interface SwapDetails {
43
+ export interface CpmmSwapQuote {
31
44
  swapType: 'ExactIn' | 'ExactOut';
32
45
  state: CpmmPoolContractState;
33
46
  tokenInInfo: TokenInfo;
@@ -39,18 +52,27 @@ export interface SwapDetails {
39
52
  priceImpact: number;
40
53
  }
41
54
 
42
- export interface AddLiquidityParams {
43
- cpmmPoolState: CpmmPoolContractState;
44
- tokenA: TokenInfo;
45
- tokenB: TokenInfo;
55
+ export interface CpmmAddLiquidityRequest {
56
+ poolState: CpmmPoolContractState;
57
+ tokenAId: CpmmTokenId;
58
+ tokenBId: CpmmTokenId;
46
59
  amountA: bigint;
47
60
  amountB: bigint;
48
- slippage: bigint; // bps
61
+ slippageBps: CpmmSlippageBps;
49
62
  sender: string;
50
- ttl?: number;
63
+ ttlMinutes?: number; // defaults to 60
51
64
  }
52
65
 
53
- export interface AddLiquidityDetails {
66
+ export interface CpmmAddLiquidityQuoteParams {
67
+ poolState?: CpmmPoolContractState;
68
+ tokenAId: CpmmTokenId;
69
+ tokenBId: CpmmTokenId;
70
+ amountA?: bigint;
71
+ amountB?: bigint;
72
+ inputType?: CpmmInputType;
73
+ }
74
+
75
+ export interface CpmmAddLiquidityQuote {
54
76
  state?: CpmmPoolContractState;
55
77
  tokenAId: string;
56
78
  tokenBId: string;
@@ -60,16 +82,16 @@ export interface AddLiquidityDetails {
60
82
  sharePercentage: number;
61
83
  }
62
84
 
63
- export interface RemoveLiquidityParams {
64
- state: CpmmPoolContractState;
85
+ export interface CpmmRemoveLiquidityRequest {
86
+ poolState: CpmmPoolContractState;
65
87
  liquidity: bigint;
66
88
  totalLiquidityAmount?: bigint;
67
- slippage: bigint; // bps
89
+ slippageBps: CpmmSlippageBps;
68
90
  sender: string;
69
- ttl?: number;
91
+ ttlMinutes?: number; // defaults to 60
70
92
  }
71
93
 
72
- export interface RemoveLiquidityDetails {
94
+ export interface CpmmRemoveLiquidityQuote {
73
95
  state: CpmmPoolContractState;
74
96
  token0: TokenInfo;
75
97
  amount0: bigint;
@@ -79,35 +101,19 @@ export interface RemoveLiquidityDetails {
79
101
  remainSharePercentage: number;
80
102
  }
81
103
 
82
- export interface ClaimableAmounts {
104
+ export interface CpmmClaimableAmounts {
83
105
  token0: TokenInfo;
84
106
  amount0: bigint;
85
107
  token1: TokenInfo;
86
108
  amount1: bigint;
87
109
  }
88
110
 
89
- export interface CreatePoolParams {
90
- tokenA: TokenInfo;
91
- tokenB: TokenInfo;
111
+ export interface CpmmCreatePoolRequest {
112
+ tokenAId: CpmmTokenId;
113
+ tokenBId: CpmmTokenId;
92
114
  sender: string;
93
- tokenAAmount?: bigint;
94
- tokenBAmount?: bigint;
95
- }
96
-
97
- export interface ComputeSwapParams {
98
- state: CpmmPoolContractState;
99
- tokenIn: TokenInfo;
100
- tokenOut: TokenInfo;
101
- amountIn?: bigint;
102
- amountOut?: bigint;
103
- slippage: bigint; // bps
104
- }
105
-
106
- export interface ComputeLiquidityParams {
107
- state?: CpmmPoolContractState;
108
- tokenA: TokenInfo;
109
- tokenB: TokenInfo;
110
- amountA?: bigint;
111
- amountB?: bigint;
112
- inputType?: 'TokenA' | 'TokenB';
115
+ initialLiquidity?: {
116
+ tokenAAmount: bigint;
117
+ tokenBAmount: bigint;
118
+ };
113
119
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './zeta';
1
+ export * from './powfi';
2
2
  export * from './common';
3
3
  export * from './cpmm';
4
4
  export * from './clmm';
package/src/moduleBase.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { Logger } from './common/logger';
2
2
  import { createLogger } from './common/logger';
3
- import type { Zeta } from './zeta';
3
+ import type { Powfi } from './powfi';
4
4
 
5
5
  export interface ModuleBaseProps {
6
- scope: Zeta;
6
+ scope: Powfi;
7
7
  moduleName: string;
8
8
  }
9
9
 
@@ -28,7 +28,7 @@ const joinMsg = (...args: unknown[]): string =>
28
28
  .join(', ');
29
29
 
30
30
  export default class ModuleBase {
31
- public scope: Zeta;
31
+ public scope: Powfi;
32
32
  private disabled = false;
33
33
  protected logger: Logger;
34
34