@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.
- package/README.md +97 -1
- package/clmm/artifacts/BitmapWord.ral.json +1 -1
- package/clmm/artifacts/BitmapWordDeployer.ral.json +1 -1
- package/clmm/artifacts/CreateConfig.ral.json +1 -1
- package/clmm/artifacts/CreateLiquidPool.ral.json +1 -1
- package/clmm/artifacts/DexAccount.ral.json +1 -1
- package/clmm/artifacts/LiquidityAmountsTest.ral.json +1 -1
- package/clmm/artifacts/LiquidityManagmentTest.ral.json +1 -1
- package/clmm/artifacts/Pool.ral.json +14 -5
- package/clmm/artifacts/PoolConfig.ral.json +1 -1
- package/clmm/artifacts/PoolFactory.ral.json +1 -1
- package/clmm/artifacts/PoolRouterDemo.ral.json +2 -2
- package/clmm/artifacts/PoolUser.ral.json +1 -1
- package/clmm/artifacts/Position.ral.json +18 -4
- package/clmm/artifacts/PositionManager.ral.json +1 -1
- package/clmm/artifacts/SwapWithoutAccount.ral.json +2 -2
- package/clmm/artifacts/TestToken.ral.json +1 -1
- package/clmm/artifacts/Tick.ral.json +1 -1
- package/clmm/artifacts/TickBitmapTest.ral.json +1 -1
- package/clmm/artifacts/ts/Pool.ts +14 -2
- package/clmm/artifacts/ts/Position.ts +37 -3
- package/cpmm/artifacts/scripts/CreatePairAndAddLiquidity.ral.json +6 -3
- package/cpmm/artifacts/ts/scripts.ts +1 -0
- package/lib/index.d.mts +242 -119
- package/lib/index.d.ts +242 -119
- package/lib/index.js +627 -329
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +628 -329
- package/lib/index.mjs.map +1 -1
- package/package.json +9 -8
- package/src/clmm/clmm.ts +70 -47
- package/src/clmm/liquidity.ts +1 -1
- package/src/clmm/pool.ts +15 -17
- package/src/clmm/tick.ts +21 -33
- package/src/clmm/types.ts +12 -12
- package/src/common/error.ts +7 -7
- package/src/common/types.ts +1 -1
- package/src/cpmm/cpmm.ts +135 -103
- package/src/cpmm/types.ts +48 -42
- package/src/index.ts +1 -1
- package/src/moduleBase.ts +3 -3
- package/src/{zeta.ts → powfi.ts} +5 -5
- package/src/staking/staking.ts +31 -24
- package/src/token/token.ts +2 -2
- package/staking/artifacts/AlphUnstakeVault.ral.json +13 -3
- package/staking/artifacts/XAlphStakeVault.ral.json +1 -1
- package/staking/artifacts/XAlphToken.ral.json +139 -6
- package/staking/artifacts/XAlphUnlockAndStartUnstake.ral.json +2 -2
- package/staking/artifacts/examples/GovernanceDemo.ral.json +1 -1
- package/staking/artifacts/examples/RewardSharingVault.ral.json +1 -1
- package/staking/artifacts/ts/AlphUnstakeVault.ts +40 -1
- package/staking/artifacts/ts/XAlphToken.ts +209 -8
- package/staking/artifacts/ts/scripts.ts +0 -10
- package/staking/artifacts/utils/FullMathTest.ral.json +1 -1
- package/staking/artifacts/utils/TestDynamicArrayByteVec32.ral.json +1 -1
- package/staking/artifacts/utils/TestDynamicSortedArrayForU256.ral.json +1 -1
- package/staking/artifacts/utils/TestMerkleProof.ral.json +1 -1
- package/staking/deployments/.deployments.devnet.json +45 -44
- package/staking/deployments/.deployments.testnet.json +23 -23
- package/staking/artifacts/AlphStakeAndLock.ral.json +0 -31
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alephium/powfi-sdk",
|
|
3
|
-
"version": "0.0.1-rc.
|
|
4
|
-
"description": "Typescript SDK for Alephium
|
|
3
|
+
"version": "0.0.1-rc.21",
|
|
4
|
+
"description": "Typescript SDK for Alephium Powfi",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.mjs",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
@@ -44,24 +44,25 @@
|
|
|
44
44
|
"defi",
|
|
45
45
|
"blockchain",
|
|
46
46
|
"sdk",
|
|
47
|
-
"
|
|
47
|
+
"powfi"
|
|
48
48
|
],
|
|
49
|
-
"author": "
|
|
50
|
-
"license": "
|
|
49
|
+
"author": "Powfi",
|
|
50
|
+
"license": "LGPL-3.0-only",
|
|
51
51
|
"repository": {
|
|
52
52
|
"type": "git",
|
|
53
|
-
"url": "https://github.com/
|
|
53
|
+
"url": "https://github.com/alephium/powfi.git"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@alephium/token-list": "0.0.20",
|
|
57
|
-
"@alephium/web3": "^2.0.
|
|
57
|
+
"@alephium/web3": "^2.0.11",
|
|
58
58
|
"decimal.js": "^10.6.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"clmm": "workspace:*",
|
|
62
62
|
"cpmm": "workspace:*",
|
|
63
63
|
"staking": "workspace:*",
|
|
64
|
-
"@alephium/web3-test": "^v2.0.
|
|
64
|
+
"@alephium/web3-test": "^v2.0.11",
|
|
65
|
+
"@alephium/web3-wallet": "^v2.0.11",
|
|
65
66
|
"@types/jest": "^29.5.12",
|
|
66
67
|
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
|
67
68
|
"@typescript-eslint/parser": "^6.17.0",
|
package/src/clmm/clmm.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SignExecuteScriptTxResult, Token } from '@alephium/web3';
|
|
2
2
|
import {
|
|
3
|
+
ALPH_TOKEN_ID,
|
|
3
4
|
addressFromContractId,
|
|
4
5
|
binToHex,
|
|
5
6
|
DUST_AMOUNT,
|
|
@@ -8,28 +9,27 @@ import {
|
|
|
8
9
|
codec,
|
|
9
10
|
encodePrimitiveValues,
|
|
10
11
|
groupOfAddress,
|
|
11
|
-
ALPH_TOKEN_ID,
|
|
12
12
|
} from '@alephium/web3';
|
|
13
13
|
import { loadDeployments } from 'clmm/artifacts/ts/deployments';
|
|
14
14
|
import ModuleBase from '../moduleBase';
|
|
15
|
-
import type {
|
|
15
|
+
import type { Powfi } from '../powfi';
|
|
16
16
|
import type {
|
|
17
|
-
|
|
17
|
+
ClmmAddLiquidityRequest,
|
|
18
18
|
ClmmConfig,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
ClmmSwapParams,
|
|
19
|
+
ClmmCollectProtocolFeesRequest,
|
|
20
|
+
ClmmCollectTokensRequest,
|
|
21
|
+
ClmmExtendRewardsRequest,
|
|
22
|
+
ClmmSimulateSwapQuote,
|
|
23
|
+
ClmmPositionInfoRequest,
|
|
25
24
|
ClmmPoolContractState,
|
|
26
25
|
ClmmPoolConfig,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
ClmmSetRewardParamsRequest,
|
|
27
|
+
ClmmSimulateSwapParams,
|
|
28
|
+
ClmmSwapRequest,
|
|
29
|
+
ClmmRemoveLiquidityRequest,
|
|
30
30
|
ClmmPositionInfo,
|
|
31
31
|
} from './types';
|
|
32
|
-
import type { PoolInstance, PoolTypes } from 'clmm/artifacts/ts';
|
|
32
|
+
import type { PoolInstance, PoolTypes, PositionManagerInstance, PositionManagerTypes } from 'clmm/artifacts/ts';
|
|
33
33
|
import {
|
|
34
34
|
CreateLiquidPool,
|
|
35
35
|
Pool,
|
|
@@ -47,7 +47,7 @@ export class ClmmModule extends ModuleBase {
|
|
|
47
47
|
private config: ClmmConfig;
|
|
48
48
|
private configsByIndex = new Map<bigint, ClmmPoolConfig>();
|
|
49
49
|
|
|
50
|
-
constructor(scope:
|
|
50
|
+
constructor(scope: Powfi) {
|
|
51
51
|
super({ scope, moduleName: 'ClmmModule' });
|
|
52
52
|
|
|
53
53
|
this.config = this._getClmmConfig();
|
|
@@ -151,7 +151,6 @@ export class ClmmModule extends ModuleBase {
|
|
|
151
151
|
const { token0, token1 } = state.fields;
|
|
152
152
|
|
|
153
153
|
const balance = await this.scope.nodeProvider.addresses.getAddressesAddressBalance(poolAddress);
|
|
154
|
-
|
|
155
154
|
const getBalance = (tokenId: string) =>
|
|
156
155
|
tokenId === ALPH_TOKEN_ID
|
|
157
156
|
? BigInt(balance.balance)
|
|
@@ -274,8 +273,15 @@ export class ClmmModule extends ModuleBase {
|
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
async addLiquidity(
|
|
277
|
-
p:
|
|
276
|
+
p: ClmmAddLiquidityRequest,
|
|
278
277
|
): Promise<{ positionId: string; result: SignExecuteScriptTxResult }> {
|
|
278
|
+
const [positionId, positionManager, params] = await this.getAddLiquidityParams(p);
|
|
279
|
+
return await this.addLiquidityFromParams(positionId, positionManager, params);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async getAddLiquidityParams(
|
|
283
|
+
p: ClmmAddLiquidityRequest,
|
|
284
|
+
): Promise<[string, PositionManagerInstance, PositionManagerTypes.SignExecuteMethodParams<'addLiquidity'>]> {
|
|
279
285
|
const poolAddress = this.getPoolAddress(p.token0, p.token1, p.configIndex);
|
|
280
286
|
const pool = Pool.at(poolAddress);
|
|
281
287
|
const positionManagerAddress = addressFromContractId(this.config.positionManagerId);
|
|
@@ -298,48 +304,47 @@ export class ClmmModule extends ModuleBase {
|
|
|
298
304
|
owner: normalizedOwner,
|
|
299
305
|
},
|
|
300
306
|
});
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
const maxTick = currentTick + p.slippage;
|
|
304
|
-
const minSqrtPriceX96 = TickUtils.getSqrtRatioAtTick(minTick);
|
|
305
|
-
const maxSqrtPriceX96 = TickUtils.getSqrtRatioAtTick(maxTick);
|
|
307
|
+
const minSqrtPriceX96 = TickUtils.getSqrtPriceLimitX96(sqrtPriceX96, p.slippage, true);
|
|
308
|
+
const maxSqrtPriceX96 = TickUtils.getSqrtPriceLimitX96(sqrtPriceX96, p.slippage, false);
|
|
306
309
|
|
|
307
|
-
const
|
|
308
|
-
|
|
310
|
+
const minLiquidity = ClmmLiquidityUtils.getLiquidityFromAmounts(
|
|
311
|
+
minSqrtPriceX96,
|
|
309
312
|
sqrtRatioAX96,
|
|
310
313
|
sqrtRatioBX96,
|
|
311
314
|
p.amount0,
|
|
312
315
|
p.amount1,
|
|
313
316
|
);
|
|
314
|
-
const [
|
|
315
|
-
|
|
317
|
+
const [, minAmount1] = ClmmLiquidityUtils.getAmountsForLiquidity(
|
|
318
|
+
minSqrtPriceX96,
|
|
316
319
|
sqrtRatioAX96,
|
|
317
320
|
sqrtRatioBX96,
|
|
318
|
-
-
|
|
321
|
+
-minLiquidity,
|
|
319
322
|
);
|
|
320
|
-
const
|
|
321
|
-
|
|
323
|
+
const maxLiquidity = ClmmLiquidityUtils.getLiquidityFromAmounts(
|
|
324
|
+
maxSqrtPriceX96,
|
|
322
325
|
sqrtRatioAX96,
|
|
323
326
|
sqrtRatioBX96,
|
|
324
|
-
|
|
327
|
+
p.amount0,
|
|
328
|
+
p.amount1,
|
|
325
329
|
);
|
|
326
|
-
const [maxAmount0
|
|
330
|
+
const [maxAmount0] = ClmmLiquidityUtils.getAmountsForLiquidity(
|
|
327
331
|
maxSqrtPriceX96,
|
|
328
332
|
sqrtRatioAX96,
|
|
329
333
|
sqrtRatioBX96,
|
|
330
|
-
-
|
|
334
|
+
-maxLiquidity,
|
|
331
335
|
);
|
|
332
336
|
|
|
333
337
|
const positionId = PoolUtils.getPositionId(poolAddress, owner, p.tickLower, p.tickUpper);
|
|
334
338
|
const tokens: Token[] = [
|
|
335
|
-
{ id: p.token0, amount:
|
|
336
|
-
{ id: p.token1, amount:
|
|
339
|
+
{ id: p.token0, amount: p.amount0 },
|
|
340
|
+
{ id: p.token1, amount: p.amount1 },
|
|
337
341
|
];
|
|
338
342
|
|
|
339
343
|
if (p.existingPosition) {
|
|
340
344
|
tokens.push({ id: positionId, amount: 1n });
|
|
341
345
|
}
|
|
342
|
-
|
|
346
|
+
|
|
347
|
+
const params = {
|
|
343
348
|
signer: this.scope.signer,
|
|
344
349
|
args: {
|
|
345
350
|
payer: normalizedPayer,
|
|
@@ -350,21 +355,32 @@ export class ClmmModule extends ModuleBase {
|
|
|
350
355
|
owner: normalizedOwner,
|
|
351
356
|
tickLower: p.tickLower,
|
|
352
357
|
tickUpper: p.tickUpper,
|
|
353
|
-
amount0Desired:
|
|
354
|
-
amount1Desired:
|
|
358
|
+
amount0Desired: p.amount0,
|
|
359
|
+
amount1Desired: p.amount1,
|
|
355
360
|
amount0Min: -maxAmount0,
|
|
356
361
|
amount1Min: -minAmount1,
|
|
357
362
|
},
|
|
358
363
|
},
|
|
359
364
|
tokens,
|
|
360
|
-
attoAlphAmount:
|
|
361
|
-
|
|
365
|
+
attoAlphAmount: this.getAddLiquidityAttoAlphAmount(p.token0, p.token1),
|
|
366
|
+
dustAmount: deposit,
|
|
367
|
+
positionId,
|
|
368
|
+
};
|
|
369
|
+
return [positionId, positionManager, params];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async addLiquidityFromParams(
|
|
373
|
+
positionId: string,
|
|
374
|
+
positionManager: PositionManagerInstance,
|
|
375
|
+
params: PositionManagerTypes.SignExecuteMethodParams<'addLiquidity'>,
|
|
376
|
+
): Promise<{ positionId: string; result: SignExecuteScriptTxResult }> {
|
|
362
377
|
|
|
378
|
+
const result = await positionManager.transact.addLiquidity(params);
|
|
363
379
|
return { positionId, result };
|
|
364
380
|
}
|
|
365
381
|
|
|
366
382
|
async removeLiquidity(
|
|
367
|
-
p:
|
|
383
|
+
p: ClmmRemoveLiquidityRequest,
|
|
368
384
|
): Promise<{ positionId: string; result: SignExecuteScriptTxResult }> {
|
|
369
385
|
const poolAddress = this.getPoolAddress(p.token0, p.token1, p.configIndex);
|
|
370
386
|
const positionManagerAddress = addressFromContractId(this.config.positionManagerId);
|
|
@@ -404,13 +420,13 @@ export class ClmmModule extends ModuleBase {
|
|
|
404
420
|
return { positionId, result };
|
|
405
421
|
}
|
|
406
422
|
|
|
407
|
-
async positionInfo({ poolId, ...args }:
|
|
423
|
+
async positionInfo({ poolId, ...args }: ClmmPositionInfoRequest): Promise<ClmmPositionInfo> {
|
|
408
424
|
const pool = Pool.at(addressFromContractId(poolId));
|
|
409
425
|
const { returns } = await pool.view.positionInfo({ args });
|
|
410
426
|
return returns;
|
|
411
427
|
}
|
|
412
428
|
async collectTokens(
|
|
413
|
-
p:
|
|
429
|
+
p: ClmmCollectTokensRequest,
|
|
414
430
|
): Promise<{ positionId: string; result: SignExecuteScriptTxResult }> {
|
|
415
431
|
const poolAddress = this.getPoolAddress(p.token0, p.token1, p.configIndex);
|
|
416
432
|
const positionId = PoolUtils.getPositionId(poolAddress, p.owner, p.tickLower, p.tickUpper);
|
|
@@ -473,7 +489,7 @@ export class ClmmModule extends ModuleBase {
|
|
|
473
489
|
return index;
|
|
474
490
|
}
|
|
475
491
|
|
|
476
|
-
async simulateSwap(p:
|
|
492
|
+
async simulateSwap(p: ClmmSimulateSwapParams): Promise<ClmmSimulateSwapQuote> {
|
|
477
493
|
const poolAddress = this.getPoolAddress(p.token0, p.token1, p.configIndex);
|
|
478
494
|
const pool = Pool.at(poolAddress);
|
|
479
495
|
const result = await pool.view.simulateSwap({
|
|
@@ -502,7 +518,7 @@ export class ClmmModule extends ModuleBase {
|
|
|
502
518
|
};
|
|
503
519
|
}
|
|
504
520
|
|
|
505
|
-
async swap(p:
|
|
521
|
+
async swap(p: ClmmSwapRequest): Promise<SignExecuteScriptTxResult> {
|
|
506
522
|
const configIndex = p.routePlan[0];
|
|
507
523
|
const pool = this.getPool(p.token0, p.token1, configIndex);
|
|
508
524
|
const poolState = await pool.fetchState();
|
|
@@ -524,12 +540,14 @@ export class ClmmModule extends ModuleBase {
|
|
|
524
540
|
sqrtPriceLimitX96,
|
|
525
541
|
data: '',
|
|
526
542
|
},
|
|
527
|
-
tokens: [{ id: tokenIn, amount: p.
|
|
543
|
+
tokens: [{ id: tokenIn, amount: p.amountIn }],
|
|
528
544
|
attoAlphAmount: DUST_AMOUNT * 2n,
|
|
529
545
|
});
|
|
530
546
|
}
|
|
531
547
|
|
|
532
|
-
async collectProtocolFees(
|
|
548
|
+
async collectProtocolFees(
|
|
549
|
+
p: ClmmCollectProtocolFeesRequest,
|
|
550
|
+
): Promise<SignExecuteScriptTxResult> {
|
|
533
551
|
const poolFactoryAddress = addressFromContractId(this.config.factoryId);
|
|
534
552
|
const poolFactory = PoolFactory.at(poolFactoryAddress);
|
|
535
553
|
const result = await poolFactory.transact.collectProtocolFees({
|
|
@@ -544,7 +562,7 @@ export class ClmmModule extends ModuleBase {
|
|
|
544
562
|
return result;
|
|
545
563
|
}
|
|
546
564
|
|
|
547
|
-
async setRewardParams(p:
|
|
565
|
+
async setRewardParams(p: ClmmSetRewardParamsRequest): Promise<SignExecuteScriptTxResult> {
|
|
548
566
|
const poolFactoryAddress = addressFromContractId(this.config.factoryId);
|
|
549
567
|
const poolFactory = PoolFactory.at(poolFactoryAddress);
|
|
550
568
|
const index = p.rewardToken === p.token0 ? 0n : p.rewardToken === p.token1 ? 1n : 2n;
|
|
@@ -567,7 +585,7 @@ export class ClmmModule extends ModuleBase {
|
|
|
567
585
|
return result;
|
|
568
586
|
}
|
|
569
587
|
|
|
570
|
-
async extendRewards(p:
|
|
588
|
+
async extendRewards(p: ClmmExtendRewardsRequest): Promise<SignExecuteScriptTxResult> {
|
|
571
589
|
const poolAddress = this.getPoolAddress(p.token0, p.token1, p.configIndex);
|
|
572
590
|
const pool = Pool.at(poolAddress);
|
|
573
591
|
const index = p.rewardToken === p.token0 ? 0n : p.rewardToken === p.token1 ? 1n : 2n;
|
|
@@ -584,6 +602,11 @@ export class ClmmModule extends ModuleBase {
|
|
|
584
602
|
return result;
|
|
585
603
|
}
|
|
586
604
|
|
|
605
|
+
private getAddLiquidityAttoAlphAmount(token0Id: string, token1Id: string): bigint {
|
|
606
|
+
const nonAlphTokenCount = [token0Id, token1Id].filter((tokenId) => tokenId !== ALPH_TOKEN_ID).length;
|
|
607
|
+
return BigInt(nonAlphTokenCount) * DUST_AMOUNT;
|
|
608
|
+
}
|
|
609
|
+
|
|
587
610
|
private _getClmmConfig(): ClmmConfig {
|
|
588
611
|
const networkId = this.scope.network.id;
|
|
589
612
|
try {
|
package/src/clmm/liquidity.ts
CHANGED
|
@@ -147,7 +147,7 @@ export class ClmmLiquidityUtils {
|
|
|
147
147
|
if (zeroForOne) {
|
|
148
148
|
return this.getToken0Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity);
|
|
149
149
|
} else {
|
|
150
|
-
return this.getToken1Delta(
|
|
150
|
+
return this.getToken1Delta(sqrtRatioBX96, sqrtRatioAX96, liquidity);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
package/src/clmm/pool.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '@alephium/web3';
|
|
8
8
|
import { Pool } from 'clmm/artifacts/ts/Pool';
|
|
9
9
|
import { TickUtils } from './tick';
|
|
10
|
-
import type {
|
|
10
|
+
import type { ClmmSimulateSwapQuote } from './types';
|
|
11
11
|
import { ClmmLiquidityUtils } from './liquidity';
|
|
12
12
|
import { MathUtil } from '../common/math';
|
|
13
13
|
import { normalizeAddress } from '../common';
|
|
@@ -38,16 +38,16 @@ export class PoolUtils {
|
|
|
38
38
|
amount: bigint,
|
|
39
39
|
feePips: bigint,
|
|
40
40
|
): [bigint, bigint, bigint, bigint] {
|
|
41
|
-
const zeroForOne = sqrtPriceX96
|
|
42
|
-
const exactIn = amount
|
|
41
|
+
const zeroForOne = sqrtPriceX96 >= sqrtPriceTargetX96;
|
|
42
|
+
const exactIn = amount >= 0n;
|
|
43
43
|
let amountIn = 0n;
|
|
44
44
|
let amountOut = 0n;
|
|
45
45
|
let feeAmount = 0n;
|
|
46
46
|
let sqrtPriceNextX96 = 0n;
|
|
47
47
|
if (exactIn) {
|
|
48
48
|
amountIn = -ClmmLiquidityUtils.getAmountDelta(
|
|
49
|
-
sqrtPriceX96,
|
|
50
49
|
sqrtPriceTargetX96,
|
|
50
|
+
sqrtPriceX96,
|
|
51
51
|
-liquidity,
|
|
52
52
|
zeroForOne,
|
|
53
53
|
);
|
|
@@ -68,44 +68,40 @@ export class PoolUtils {
|
|
|
68
68
|
sqrtPriceTargetX96,
|
|
69
69
|
sqrtPriceX96,
|
|
70
70
|
liquidity,
|
|
71
|
-
zeroForOne,
|
|
71
|
+
!zeroForOne,
|
|
72
72
|
);
|
|
73
73
|
const sqrtPriceRealTargetX96 = TickUtils.getNextSqrtPrice(
|
|
74
74
|
sqrtPriceX96,
|
|
75
75
|
liquidity,
|
|
76
76
|
amount,
|
|
77
|
-
zeroForOne,
|
|
77
|
+
!zeroForOne,
|
|
78
78
|
);
|
|
79
79
|
sqrtPriceNextX96 = -amount >= amountOut ? sqrtPriceTargetX96 : sqrtPriceRealTargetX96;
|
|
80
80
|
}
|
|
81
81
|
const max = sqrtPriceTargetX96 == sqrtPriceNextX96;
|
|
82
82
|
if (zeroForOne) {
|
|
83
|
-
const amountIn2 = -ClmmLiquidityUtils.
|
|
83
|
+
const amountIn2 = -ClmmLiquidityUtils.getToken0Delta(
|
|
84
84
|
sqrtPriceNextX96,
|
|
85
85
|
sqrtPriceX96,
|
|
86
86
|
-liquidity,
|
|
87
|
-
zeroForOne,
|
|
88
87
|
);
|
|
89
|
-
const amountOut2 = ClmmLiquidityUtils.
|
|
88
|
+
const amountOut2 = ClmmLiquidityUtils.getToken1Delta(
|
|
90
89
|
sqrtPriceNextX96,
|
|
91
90
|
sqrtPriceX96,
|
|
92
91
|
liquidity,
|
|
93
|
-
zeroForOne,
|
|
94
92
|
);
|
|
95
93
|
amountIn = max && exactIn ? amountIn : amountIn2;
|
|
96
94
|
amountOut = max && !exactIn ? amountOut : amountOut2;
|
|
97
95
|
} else {
|
|
98
|
-
const amountIn2 = -ClmmLiquidityUtils.
|
|
96
|
+
const amountIn2 = -ClmmLiquidityUtils.getToken1Delta(
|
|
99
97
|
sqrtPriceX96,
|
|
100
98
|
sqrtPriceNextX96,
|
|
101
99
|
-liquidity,
|
|
102
|
-
zeroForOne,
|
|
103
100
|
);
|
|
104
|
-
const amountOut2 = ClmmLiquidityUtils.
|
|
101
|
+
const amountOut2 = ClmmLiquidityUtils.getToken0Delta(
|
|
105
102
|
sqrtPriceX96,
|
|
106
103
|
sqrtPriceNextX96,
|
|
107
104
|
liquidity,
|
|
108
|
-
zeroForOne,
|
|
109
105
|
);
|
|
110
106
|
amountIn = max && exactIn ? amountIn : amountIn2;
|
|
111
107
|
amountOut = max && !exactIn ? amountOut : amountOut2;
|
|
@@ -115,24 +111,25 @@ export class PoolUtils {
|
|
|
115
111
|
if (exactIn && sqrtPriceNextX96 != sqrtPriceTargetX96) {
|
|
116
112
|
feeAmount = amount - amountIn;
|
|
117
113
|
} else {
|
|
118
|
-
feeAmount = MathUtil.
|
|
114
|
+
feeAmount = -MathUtil.alphDiv(-amountIn * feePips, Pool.consts.MAX_PIPS - feePips);
|
|
119
115
|
}
|
|
120
116
|
|
|
121
117
|
return [sqrtPriceNextX96, amountIn, amountOut, feeAmount];
|
|
122
118
|
}
|
|
123
119
|
|
|
124
120
|
static offlineSwap(
|
|
125
|
-
liqDist:
|
|
121
|
+
liqDist: ClmmSimulateSwapQuote,
|
|
126
122
|
amountSpecified: bigint,
|
|
127
123
|
sqrtPriceX96: bigint,
|
|
128
124
|
): bigint {
|
|
129
125
|
const exactIn = amountSpecified > 0n;
|
|
130
126
|
let amountCalculated = 0n;
|
|
127
|
+
let liquidity = liqDist.liquidity;
|
|
131
128
|
for (const row of liqDist.rows) {
|
|
132
129
|
const [sqrtPriceNextX96, amountIn, amountOut, feeAmount] = this.computeSwapStep(
|
|
133
130
|
sqrtPriceX96,
|
|
134
131
|
row.sqrtPriceX96,
|
|
135
|
-
|
|
132
|
+
liquidity,
|
|
136
133
|
amountSpecified,
|
|
137
134
|
liqDist.fee,
|
|
138
135
|
);
|
|
@@ -144,6 +141,7 @@ export class PoolUtils {
|
|
|
144
141
|
amountCalculated += amountIn + feeAmount;
|
|
145
142
|
}
|
|
146
143
|
sqrtPriceX96 = sqrtPriceNextX96;
|
|
144
|
+
liquidity = row.liquidity;
|
|
147
145
|
}
|
|
148
146
|
return amountCalculated;
|
|
149
147
|
}
|
package/src/clmm/tick.ts
CHANGED
|
@@ -247,19 +247,6 @@ export class TickUtils {
|
|
|
247
247
|
return this.getPriceFromTick(tick, tokenBase, tokenQuote, baseIn);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
static getNextSqrtPrice(
|
|
251
|
-
sqrtPriceX96: bigint,
|
|
252
|
-
liquidity: bigint,
|
|
253
|
-
amount: bigint,
|
|
254
|
-
zeroForOne: boolean,
|
|
255
|
-
): bigint {
|
|
256
|
-
if (zeroForOne) {
|
|
257
|
-
return this.getNextSqrtPriceFromAmount0(sqrtPriceX96, liquidity, amount);
|
|
258
|
-
} else {
|
|
259
|
-
return this.getNextSqrtPriceFromAmount1(sqrtPriceX96, liquidity, amount);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
250
|
static getNextSqrtPriceFromAmount0(
|
|
264
251
|
sqrtPriceX96: bigint,
|
|
265
252
|
liquidity: bigint,
|
|
@@ -267,11 +254,11 @@ export class TickUtils {
|
|
|
267
254
|
): bigint {
|
|
268
255
|
const numerator1 = liquidity * Q96;
|
|
269
256
|
const product = amount * sqrtPriceX96;
|
|
270
|
-
|
|
257
|
+
const denominator = numerator1 - product;
|
|
258
|
+
if (denominator <= 0n) {
|
|
271
259
|
throw new Error('Amount0 exceeds available liquidity for the swap');
|
|
272
260
|
}
|
|
273
|
-
|
|
274
|
-
return MathUtil.alphDiv(numerator1 * sqrtPriceX96, denominator);
|
|
261
|
+
return -MathUtil.alphDiv(-numerator1 * sqrtPriceX96, denominator);
|
|
275
262
|
}
|
|
276
263
|
|
|
277
264
|
static getNextSqrtPriceFromAmount1(
|
|
@@ -283,9 +270,22 @@ export class TickUtils {
|
|
|
283
270
|
return sqrtPriceX96 + quotient;
|
|
284
271
|
}
|
|
285
272
|
|
|
273
|
+
static getNextSqrtPrice(
|
|
274
|
+
sqrtPX96: bigint,
|
|
275
|
+
liquidity: bigint,
|
|
276
|
+
amount: bigint,
|
|
277
|
+
zeroForOne: boolean,
|
|
278
|
+
): bigint {
|
|
279
|
+
if (zeroForOne) {
|
|
280
|
+
return this.getNextSqrtPriceFromAmount0(sqrtPX96, liquidity, amount);
|
|
281
|
+
} else {
|
|
282
|
+
return this.getNextSqrtPriceFromAmount1(sqrtPX96, liquidity, amount);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
286
|
static getSqrtPriceLimitX96(sqrtPriceX96: bigint, slippage: bigint, zeroForOne: boolean): bigint {
|
|
287
|
-
if (slippage
|
|
288
|
-
throw new Error('slippageBps must be in
|
|
287
|
+
if (slippage < 0n || slippage >= BPS) {
|
|
288
|
+
throw new Error('slippageBps must be in [0, 10000)');
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
const [minBound, maxBound] = this.getSqrtPriceX96Bounds(sqrtPriceX96, slippage);
|
|
@@ -311,21 +311,9 @@ export class TickUtils {
|
|
|
311
311
|
if (slippage < 0n || slippage >= BPS) {
|
|
312
312
|
throw new Error('Invalid slippageBps; must be in [0, 10000)');
|
|
313
313
|
}
|
|
314
|
-
const
|
|
315
|
-
const
|
|
316
|
-
const
|
|
317
|
-
const factorMinusQ96 = MathUtil.mulDivFloor(
|
|
318
|
-
MathUtil.sqrt(numMinus) * Q96,
|
|
319
|
-
1n,
|
|
320
|
-
MathUtil.sqrt(den),
|
|
321
|
-
);
|
|
322
|
-
const factorPlusQ96 = MathUtil.mulDivFloor(
|
|
323
|
-
MathUtil.sqrt(numPlus) * Q96,
|
|
324
|
-
1n,
|
|
325
|
-
MathUtil.sqrt(den),
|
|
326
|
-
);
|
|
327
|
-
const minSqrtPriceX96 = MathUtil.mulDivFloor(sqrtPriceX96, factorMinusQ96, Q96);
|
|
328
|
-
const maxSqrtPriceX96 = (sqrtPriceX96 * factorPlusQ96 + Q96 - 1n) / Q96;
|
|
314
|
+
const price = sqrtPriceX96 * sqrtPriceX96;
|
|
315
|
+
const minSqrtPriceX96 = MathUtil.sqrt(price * (BPS - slippage) / BPS);
|
|
316
|
+
const maxSqrtPriceX96 = MathUtil.sqrt(price * (BPS + slippage) / BPS);
|
|
329
317
|
return [minSqrtPriceX96, maxSqrtPriceX96];
|
|
330
318
|
}
|
|
331
319
|
|
package/src/clmm/types.ts
CHANGED
|
@@ -10,15 +10,16 @@ export interface ClmmConfig {
|
|
|
10
10
|
accountRoot: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export interface
|
|
13
|
+
export interface ClmmSwapRequest {
|
|
14
14
|
token0: string;
|
|
15
15
|
token1: string;
|
|
16
16
|
amount: bigint;
|
|
17
|
+
amountIn: bigint;
|
|
17
18
|
slippage: bigint;
|
|
18
19
|
routePlan: bigint[];
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export interface
|
|
22
|
+
export interface ClmmSimulateSwapParams {
|
|
22
23
|
configIndex: bigint;
|
|
23
24
|
token0: string;
|
|
24
25
|
token1: string;
|
|
@@ -31,7 +32,7 @@ export interface LiquidityForPrice {
|
|
|
31
32
|
sqrtPriceX96: bigint;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
export interface
|
|
35
|
+
export interface ClmmSimulateSwapQuote {
|
|
35
36
|
baseSqrtPriceX96: bigint;
|
|
36
37
|
sqrtPriceX96: bigint;
|
|
37
38
|
liquidity: bigint;
|
|
@@ -39,7 +40,7 @@ export interface LiquidityDistribution {
|
|
|
39
40
|
rows: Array<LiquidityForPrice>;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
export interface
|
|
43
|
+
export interface ClmmAddLiquidityRequest {
|
|
43
44
|
token0: string;
|
|
44
45
|
token1: string;
|
|
45
46
|
configIndex: bigint;
|
|
@@ -52,7 +53,7 @@ export interface AddLiquidity {
|
|
|
52
53
|
existingPosition?: boolean;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export interface
|
|
56
|
+
export interface ClmmRemoveLiquidityRequest {
|
|
56
57
|
token0: string;
|
|
57
58
|
token1: string;
|
|
58
59
|
configIndex: bigint;
|
|
@@ -65,7 +66,7 @@ export interface RemoveLiquidity {
|
|
|
65
66
|
otherAmountMax: bigint;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
export interface
|
|
69
|
+
export interface ClmmCollectTokensRequest {
|
|
69
70
|
token0: string;
|
|
70
71
|
token1: string;
|
|
71
72
|
configIndex: bigint;
|
|
@@ -78,7 +79,7 @@ export interface CollectTokens {
|
|
|
78
79
|
amount1Max: bigint;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
export interface
|
|
82
|
+
export interface ClmmPositionInfoRequest {
|
|
82
83
|
poolId: string;
|
|
83
84
|
owner: string;
|
|
84
85
|
tickLower: bigint;
|
|
@@ -90,14 +91,14 @@ export interface PositionPath {
|
|
|
90
91
|
acct0: bigint;
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
export interface
|
|
94
|
+
export interface ClmmCollectProtocolFeesRequest {
|
|
94
95
|
token0: string;
|
|
95
96
|
token1: string;
|
|
96
97
|
configIndex: bigint;
|
|
97
98
|
recipient: string;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
export interface
|
|
101
|
+
export interface ClmmSetRewardParamsRequest {
|
|
101
102
|
token0: string;
|
|
102
103
|
token1: string;
|
|
103
104
|
configIndex: bigint;
|
|
@@ -108,7 +109,7 @@ export interface SetRewardParams {
|
|
|
108
109
|
endTime: bigint;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
export interface
|
|
112
|
+
export interface ClmmExtendRewardsRequest {
|
|
112
113
|
token0: string;
|
|
113
114
|
token1: string;
|
|
114
115
|
configIndex: bigint;
|
|
@@ -135,8 +136,7 @@ export interface ClmmPoolConfig {
|
|
|
135
136
|
|
|
136
137
|
export const MAX_PIPS = Pool.consts.MAX_PIPS;
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
export type ClmmPositionInfo = PositionInfo
|
|
139
|
+
export type ClmmPositionInfo = PositionInfo;
|
|
140
140
|
|
|
141
141
|
export interface GetPositionAmountsFromPriceProps {
|
|
142
142
|
sqrtRatioX96: bigint;
|
package/src/common/error.ts
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
export class
|
|
1
|
+
export class PowfiSDKError extends Error {
|
|
2
2
|
constructor(message: string, options?: ErrorOptions) {
|
|
3
3
|
super(message, options);
|
|
4
|
-
this.name = '
|
|
4
|
+
this.name = 'PowfiSDKError';
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export class InsufficientLiquidityError extends
|
|
8
|
+
export class InsufficientLiquidityError extends PowfiSDKError {
|
|
9
9
|
constructor(message: string = 'Insufficient liquidity') {
|
|
10
10
|
super(message);
|
|
11
11
|
this.name = 'InsufficientLiquidityError';
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export class PriceImpactTooHighError extends
|
|
15
|
+
export class PriceImpactTooHighError extends PowfiSDKError {
|
|
16
16
|
constructor(priceImpact: number, maxPriceImpact: number) {
|
|
17
17
|
super(`Price impact too high: ${priceImpact.toFixed(2)}% > ${maxPriceImpact}%`);
|
|
18
18
|
this.name = 'PriceImpactTooHighError';
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export class PoolNotFoundError extends
|
|
22
|
+
export class PoolNotFoundError extends PowfiSDKError {
|
|
23
23
|
constructor(poolId: string) {
|
|
24
24
|
super(`Pool does not exist for ${poolId}`);
|
|
25
25
|
this.name = 'PoolNotFoundError';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export class InsufficientBalanceError extends
|
|
29
|
+
export class InsufficientBalanceError extends PowfiSDKError {
|
|
30
30
|
constructor(token: string, required: string, available: string) {
|
|
31
31
|
super(`Not enough ${token} balance. Required: ${required}, Available: ${available}`);
|
|
32
32
|
this.name = 'InsufficientBalanceError';
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export class TokenListFetchError extends
|
|
36
|
+
export class TokenListFetchError extends PowfiSDKError {
|
|
37
37
|
public readonly status?: number;
|
|
38
38
|
|
|
39
39
|
constructor(url: string, options?: { status?: number; cause?: unknown }) {
|
package/src/common/types.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const defaultNetworks: Network[] = [
|
|
|
42
42
|
];
|
|
43
43
|
export type NetworkOverrides = Partial<Omit<Network, 'id'>>;
|
|
44
44
|
|
|
45
|
-
export interface
|
|
45
|
+
export interface PowfiLoadParams {
|
|
46
46
|
networkId: NetworkId;
|
|
47
47
|
signer?: SignerProvider;
|
|
48
48
|
networkOverrides?: NetworkOverrides;
|