@whetstone-research/doppler-sdk 1.0.1 → 1.0.4
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 +23 -19
- package/dist/{chunk-LIXSTCMM.js → chunk-BSHIMMA4.js} +74 -31
- package/dist/chunk-BSHIMMA4.js.map +1 -0
- package/dist/chunk-BXATWUGJ.cjs +1111 -0
- package/dist/chunk-BXATWUGJ.cjs.map +1 -0
- package/dist/chunk-DPKVNI6Q.cjs +351 -0
- package/dist/chunk-DPKVNI6Q.cjs.map +1 -0
- package/dist/{chunk-T46KDO65.js → chunk-J57ROY36.js} +16 -29
- package/dist/chunk-J57ROY36.js.map +1 -0
- package/dist/chunk-Q7SFCCGT.cjs +11 -0
- package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
- package/dist/evm/index.cjs +15410 -0
- package/dist/evm/index.cjs.map +1 -0
- package/dist/evm/index.d.cts +8533 -0
- package/dist/evm/index.js +2 -2
- package/dist/evm/index.js.map +1 -1
- package/dist/{oracle-B2LV97ff.d.ts → oracle-CU-nZnja.d.cts} +1 -1
- package/dist/oracle-CU-nZnja.d.ts +826 -0
- package/dist/{pda-LKHUH6JK.js → pda-TXZDXZZ4.js} +3 -3
- package/dist/pda-TXZDXZZ4.js.map +1 -0
- package/dist/pda-ZZMBZSFU.cjs +53 -0
- package/dist/pda-ZZMBZSFU.cjs.map +1 -0
- package/dist/solana/index.cjs +4981 -0
- package/dist/solana/index.cjs.map +1 -0
- package/dist/solana/index.d.cts +4584 -0
- package/dist/solana/index.d.ts +2212 -162
- package/dist/solana/index.js +3163 -486
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/react/index.cjs +1465 -0
- package/dist/solana/react/index.cjs.map +1 -0
- package/dist/solana/react/index.d.cts +1046 -0
- package/dist/solana/react/index.d.ts +1 -1
- package/dist/solana/react/index.js +5 -5
- package/dist/solana/react/index.js.map +1 -1
- package/package.json +17 -9
- package/dist/chunk-LIXSTCMM.js.map +0 -1
- package/dist/chunk-T46KDO65.js.map +0 -1
- package/dist/pda-LKHUH6JK.js.map +0 -1
package/README.md
CHANGED
|
@@ -26,10 +26,14 @@ yarn add @whetstone-research/doppler-sdk viem
|
|
|
26
26
|
pnpm add @whetstone-research/doppler-sdk viem
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Import EVM APIs from `@whetstone-research/doppler-sdk/evm`. Solana APIs live under
|
|
30
|
+
`@whetstone-research/doppler-sdk/solana` and React bindings under
|
|
31
|
+
`@whetstone-research/doppler-sdk/solana/react`.
|
|
32
|
+
|
|
29
33
|
## Quick Start
|
|
30
34
|
|
|
31
35
|
```typescript
|
|
32
|
-
import { DopplerSDK } from '@whetstone-research/doppler-sdk';
|
|
36
|
+
import { DopplerSDK } from '@whetstone-research/doppler-sdk/evm';
|
|
33
37
|
import { createPublicClient, createWalletClient, http } from 'viem';
|
|
34
38
|
import { base } from 'viem/chains';
|
|
35
39
|
|
|
@@ -60,7 +64,7 @@ const sdk = new DopplerSDK({
|
|
|
60
64
|
Static auctions use Uniswap V3 pools with concentrated liquidity in a fixed price range. They're ideal for simple, predictable price discovery.
|
|
61
65
|
|
|
62
66
|
```typescript
|
|
63
|
-
import { StaticAuctionBuilder } from '@whetstone-research/doppler-sdk';
|
|
67
|
+
import { StaticAuctionBuilder } from '@whetstone-research/doppler-sdk/evm';
|
|
64
68
|
|
|
65
69
|
const params = new StaticAuctionBuilder()
|
|
66
70
|
.tokenConfig({
|
|
@@ -105,7 +109,7 @@ import {
|
|
|
105
109
|
StaticAuctionBuilder,
|
|
106
110
|
WAD,
|
|
107
111
|
getAirlockOwner,
|
|
108
|
-
} from '@whetstone-research/doppler-sdk';
|
|
112
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
109
113
|
import { parseEther } from 'viem';
|
|
110
114
|
|
|
111
115
|
// Get the protocol owner (required beneficiary with min 5%)
|
|
@@ -164,7 +168,7 @@ Dynamic auctions use Uniswap V4 hooks to implement gradual Dutch auctions where
|
|
|
164
168
|
import {
|
|
165
169
|
DynamicAuctionBuilder,
|
|
166
170
|
DAY_SECONDS,
|
|
167
|
-
} from '@whetstone-research/doppler-sdk';
|
|
171
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
168
172
|
|
|
169
173
|
const params = new DynamicAuctionBuilder()
|
|
170
174
|
.tokenConfig({
|
|
@@ -299,7 +303,7 @@ Multicurve auctions use a Uniswap V4-style initializer that seeds liquidity acro
|
|
|
299
303
|
**Standard Multicurve with Migration:**
|
|
300
304
|
|
|
301
305
|
```typescript
|
|
302
|
-
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk';
|
|
306
|
+
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk/evm';
|
|
303
307
|
import { parseEther } from 'viem';
|
|
304
308
|
import { base } from 'viem/chains';
|
|
305
309
|
|
|
@@ -346,7 +350,7 @@ console.log('Token address:', result.tokenAddress);
|
|
|
346
350
|
**Market Cap Presets (Low / Medium / High):**
|
|
347
351
|
|
|
348
352
|
```typescript
|
|
349
|
-
import { MulticurveBuilder, FEE_TIERS } from '@whetstone-research/doppler-sdk';
|
|
353
|
+
import { MulticurveBuilder, FEE_TIERS } from '@whetstone-research/doppler-sdk/evm';
|
|
350
354
|
import { parseEther } from 'viem';
|
|
351
355
|
import { base } from 'viem/chains';
|
|
352
356
|
|
|
@@ -387,7 +391,7 @@ Pass `presets` to pick a subset (e.g. `['medium', 'high']`) or provide `override
|
|
|
387
391
|
**Scheduled Multicurve Launch:**
|
|
388
392
|
|
|
389
393
|
```typescript
|
|
390
|
-
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk';
|
|
394
|
+
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk/evm';
|
|
391
395
|
import { parseEther } from 'viem';
|
|
392
396
|
import { base } from 'viem/chains';
|
|
393
397
|
|
|
@@ -438,7 +442,7 @@ Ensure the target chain has the scheduled multicurve initializer whitelisted. If
|
|
|
438
442
|
**Decay Multicurve Launch (Dynamic Fee):**
|
|
439
443
|
|
|
440
444
|
```typescript
|
|
441
|
-
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk';
|
|
445
|
+
import { MulticurveBuilder } from '@whetstone-research/doppler-sdk/evm';
|
|
442
446
|
import { parseEther } from 'viem';
|
|
443
447
|
import { baseSepolia } from 'viem/chains';
|
|
444
448
|
|
|
@@ -495,7 +499,7 @@ For decay pools, `pool.fee` is always the terminal fee (`endFee`) of the schedul
|
|
|
495
499
|
When you want fee revenue to flow to specific addresses without migrating liquidity after the auction, use lockable beneficiaries with NoOp migration:
|
|
496
500
|
|
|
497
501
|
```typescript
|
|
498
|
-
import { WAD } from '@whetstone-research/doppler-sdk';
|
|
502
|
+
import { WAD } from '@whetstone-research/doppler-sdk/evm';
|
|
499
503
|
|
|
500
504
|
// Define beneficiaries with shares that sum to WAD (1e18 = 100%)
|
|
501
505
|
// IMPORTANT: Protocol owner must be included with at least 5% shares
|
|
@@ -575,7 +579,7 @@ Prefer using the builders to construct `CreateStaticAuctionParams` and `CreateDy
|
|
|
575
579
|
import {
|
|
576
580
|
StaticAuctionBuilder,
|
|
577
581
|
DynamicAuctionBuilder,
|
|
578
|
-
} from '@whetstone-research/doppler-sdk';
|
|
582
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
579
583
|
import { parseEther } from 'viem';
|
|
580
584
|
|
|
581
585
|
// Dynamic auction via builder
|
|
@@ -807,7 +811,7 @@ await token.release();
|
|
|
807
811
|
Alternatively, you can instantiate directly if needed:
|
|
808
812
|
|
|
809
813
|
```typescript
|
|
810
|
-
import { Derc20 } from '@whetstone-research/doppler-sdk';
|
|
814
|
+
import { Derc20 } from '@whetstone-research/doppler-sdk/evm';
|
|
811
815
|
const tokenDirect = new Derc20(publicClient, walletClient, tokenAddress);
|
|
812
816
|
```
|
|
813
817
|
|
|
@@ -818,7 +822,7 @@ DERC20 extends OpenZeppelin's ERC20Votes. Voting power is tracked via checkpoint
|
|
|
818
822
|
Basics:
|
|
819
823
|
|
|
820
824
|
```ts
|
|
821
|
-
import { Derc20 } from '@whetstone-research/doppler-sdk';
|
|
825
|
+
import { Derc20 } from '@whetstone-research/doppler-sdk/evm';
|
|
822
826
|
|
|
823
827
|
const token = sdk.getDerc20(tokenAddress);
|
|
824
828
|
|
|
@@ -924,7 +928,7 @@ Notes
|
|
|
924
928
|
The SDK also provides an ETH wrapper with ERC20-like interface:
|
|
925
929
|
|
|
926
930
|
```typescript
|
|
927
|
-
import { Eth } from '@whetstone-research/doppler-sdk';
|
|
931
|
+
import { Eth } from '@whetstone-research/doppler-sdk/evm';
|
|
928
932
|
|
|
929
933
|
const eth = new Eth(publicClient, walletClient);
|
|
930
934
|
const balance = await eth.getBalanceOf(address);
|
|
@@ -1138,7 +1142,7 @@ import {
|
|
|
1138
1142
|
DopplerSDK,
|
|
1139
1143
|
createAirlockBeneficiary,
|
|
1140
1144
|
getAirlockOwner,
|
|
1141
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1145
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1142
1146
|
import { parseEther } from 'viem';
|
|
1143
1147
|
|
|
1144
1148
|
const sdk = new DopplerSDK({ publicClient, chainId });
|
|
@@ -1177,7 +1181,7 @@ import {
|
|
|
1177
1181
|
isSupportedChainId,
|
|
1178
1182
|
type SupportedChainId,
|
|
1179
1183
|
type ChainAddresses,
|
|
1180
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1184
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1181
1185
|
|
|
1182
1186
|
// Validate and narrow a chain ID
|
|
1183
1187
|
function ensureSupported(id: number): SupportedChainId {
|
|
@@ -1228,7 +1232,7 @@ import {
|
|
|
1228
1232
|
StaticAuctionBuilder,
|
|
1229
1233
|
mineTokenAddress,
|
|
1230
1234
|
getAddresses,
|
|
1231
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1235
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1232
1236
|
import { parseEther } from 'viem';
|
|
1233
1237
|
import { base } from 'viem/chains';
|
|
1234
1238
|
|
|
@@ -1296,7 +1300,7 @@ import {
|
|
|
1296
1300
|
getAddresses,
|
|
1297
1301
|
DopplerBytecode,
|
|
1298
1302
|
DAY_SECONDS,
|
|
1299
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1303
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1300
1304
|
import { parseEther, keccak256, encodePacked, encodeAbiParameters } from 'viem';
|
|
1301
1305
|
import { base } from 'viem/chains';
|
|
1302
1306
|
|
|
@@ -1391,7 +1395,7 @@ import {
|
|
|
1391
1395
|
MulticurveBuilder,
|
|
1392
1396
|
mineTokenAddress,
|
|
1393
1397
|
getAddresses,
|
|
1394
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1398
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1395
1399
|
import { parseEther } from 'viem';
|
|
1396
1400
|
import { base } from 'viem/chains';
|
|
1397
1401
|
|
|
@@ -1521,7 +1525,7 @@ import type {
|
|
|
1521
1525
|
PoolInfo,
|
|
1522
1526
|
HookInfo,
|
|
1523
1527
|
VestingConfig,
|
|
1524
|
-
} from '@whetstone-research/doppler-sdk';
|
|
1528
|
+
} from '@whetstone-research/doppler-sdk/evm';
|
|
1525
1529
|
```
|
|
1526
1530
|
|
|
1527
1531
|
## Development
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MAX_SENTINEL_ALLOWLIST, MAX_ORACLE_OBSERVATIONS, ACCOUNT_DISCRIMINATORS,
|
|
2
|
-
import { getAddressCodec, getBooleanCodec, getU8Codec, getU16Codec, getU32Codec, getU64Codec, getU128Codec, transformCodec, getArrayCodec, fixCodecSize, getBytesCodec, getStructCodec, getHiddenPrefixDecoder, getConstantDecoder, getOptionCodec, unwrapOption, mergeBytes } from '@solana/kit';
|
|
1
|
+
import { MAX_SENTINEL_ALLOWLIST, MAX_ORACLE_OBSERVATIONS, ACCOUNT_DISCRIMINATORS, CPMM_PROGRAM_ID, Q64_ONE, BPS_DENOM, TOKEN_PROGRAM_ADDRESS, INSTRUCTION_DISCRIMINATORS, getPoolAddress, sortMints, getPositionAddress, getOracleAddress } from './chunk-J57ROY36.js';
|
|
2
|
+
import { getAddressCodec, getBooleanCodec, getU8Codec, getU16Codec, getU32Codec, getU64Codec, getU128Codec, transformCodec, getArrayCodec, fixCodecSize, getBytesCodec, getStructCodec, getHiddenPrefixDecoder, getConstantDecoder, getOptionCodec, unwrapOption, mergeBytes, AccountRole } from '@solana/kit';
|
|
3
3
|
|
|
4
4
|
var addressCodec = getAddressCodec();
|
|
5
5
|
var boolCodec = getBooleanCodec();
|
|
@@ -176,7 +176,7 @@ var addLiquidityArgsWithOracleCodec = getStructCodec([
|
|
|
176
176
|
["minSharesOut", u128Codec],
|
|
177
177
|
["updateOracle", boolCodec]
|
|
178
178
|
]);
|
|
179
|
-
transformCodec(
|
|
179
|
+
var addLiquidityArgsCodec = transformCodec(
|
|
180
180
|
addLiquidityArgsWithOracleCodec,
|
|
181
181
|
(value) => ({
|
|
182
182
|
...value,
|
|
@@ -247,6 +247,51 @@ var quoteToNumeraireArgsCodec = getStructCodec([
|
|
|
247
247
|
["useTwap", boolCodec],
|
|
248
248
|
["windowSeconds", u32Codec]
|
|
249
249
|
]);
|
|
250
|
+
function encodeSwapExactInArgs(args) {
|
|
251
|
+
return new Uint8Array(swapExactInArgsCodec.encode(args));
|
|
252
|
+
}
|
|
253
|
+
function encodeAddLiquidityArgs(args) {
|
|
254
|
+
return new Uint8Array(addLiquidityArgsCodec.encode(args));
|
|
255
|
+
}
|
|
256
|
+
function encodeRemoveLiquidityArgs(args) {
|
|
257
|
+
return new Uint8Array(removeLiquidityArgsCodec.encode(args));
|
|
258
|
+
}
|
|
259
|
+
function encodeCollectFeesArgs(args) {
|
|
260
|
+
return new Uint8Array(collectFeesArgsCodec.encode(args));
|
|
261
|
+
}
|
|
262
|
+
function encodeCollectProtocolFeesArgs(args) {
|
|
263
|
+
return new Uint8Array(collectProtocolFeesArgsCodec.encode(args));
|
|
264
|
+
}
|
|
265
|
+
function encodeCreatePositionArgs(args) {
|
|
266
|
+
return new Uint8Array(createPositionArgsCodec.encode(args));
|
|
267
|
+
}
|
|
268
|
+
function encodeInitializeConfigArgs(args) {
|
|
269
|
+
return new Uint8Array(initializeConfigArgsCodec.encode(args));
|
|
270
|
+
}
|
|
271
|
+
function encodeInitializePoolArgs(args) {
|
|
272
|
+
return new Uint8Array(initializePoolArgsCodec.encode(args));
|
|
273
|
+
}
|
|
274
|
+
function encodeInitializeOracleArgs(args) {
|
|
275
|
+
return new Uint8Array(initializeOracleArgsCodec.encode(args));
|
|
276
|
+
}
|
|
277
|
+
function encodeSetSentinelArgs(args) {
|
|
278
|
+
return new Uint8Array(setSentinelArgsCodec.encode(args));
|
|
279
|
+
}
|
|
280
|
+
function encodeSetFeesArgs(args) {
|
|
281
|
+
return new Uint8Array(setFeesArgsCodec.encode(args));
|
|
282
|
+
}
|
|
283
|
+
function encodeSetRouteArgs(args) {
|
|
284
|
+
return new Uint8Array(setRouteArgsCodec.encode(args));
|
|
285
|
+
}
|
|
286
|
+
function encodeTransferAdminArgs(args) {
|
|
287
|
+
return new Uint8Array(transferAdminArgsCodec.encode(args));
|
|
288
|
+
}
|
|
289
|
+
function encodeOracleConsultArgs(args) {
|
|
290
|
+
return new Uint8Array(oracleConsultArgsCodec.encode(args));
|
|
291
|
+
}
|
|
292
|
+
function encodeQuoteToNumeraireArgs(args) {
|
|
293
|
+
return new Uint8Array(quoteToNumeraireArgsCodec.encode(args));
|
|
294
|
+
}
|
|
250
295
|
|
|
251
296
|
// src/solana/core/math.ts
|
|
252
297
|
function q64ToNumber(q64) {
|
|
@@ -441,9 +486,7 @@ function calculateTwapNumber(cumulativeStart, cumulativeEnd, timestampStart, tim
|
|
|
441
486
|
);
|
|
442
487
|
return q64ToNumber(twapQ64);
|
|
443
488
|
}
|
|
444
|
-
|
|
445
|
-
// src/solana/instructions/collectFees.ts
|
|
446
|
-
function createCollectFeesInstruction(accounts, args, programId = PROGRAM_ID) {
|
|
489
|
+
function createCollectFeesInstruction(accounts, args, programId = CPMM_PROGRAM_ID) {
|
|
447
490
|
const {
|
|
448
491
|
pool,
|
|
449
492
|
position,
|
|
@@ -455,20 +498,20 @@ function createCollectFeesInstruction(accounts, args, programId = PROGRAM_ID) {
|
|
|
455
498
|
token1Mint,
|
|
456
499
|
user0,
|
|
457
500
|
user1,
|
|
458
|
-
tokenProgram =
|
|
501
|
+
tokenProgram = TOKEN_PROGRAM_ADDRESS
|
|
459
502
|
} = accounts;
|
|
460
503
|
const keys = [
|
|
461
|
-
{ address: pool, role:
|
|
462
|
-
{ address: position, role:
|
|
463
|
-
{ address: owner, role:
|
|
464
|
-
{ address: authority, role:
|
|
465
|
-
{ address: vault0, role:
|
|
466
|
-
{ address: vault1, role:
|
|
467
|
-
{ address: token0Mint, role:
|
|
468
|
-
{ address: token1Mint, role:
|
|
469
|
-
{ address: user0, role:
|
|
470
|
-
{ address: user1, role:
|
|
471
|
-
{ address: tokenProgram, role:
|
|
504
|
+
{ address: pool, role: AccountRole.WRITABLE },
|
|
505
|
+
{ address: position, role: AccountRole.WRITABLE },
|
|
506
|
+
{ address: owner, role: AccountRole.READONLY_SIGNER },
|
|
507
|
+
{ address: authority, role: AccountRole.READONLY },
|
|
508
|
+
{ address: vault0, role: AccountRole.WRITABLE },
|
|
509
|
+
{ address: vault1, role: AccountRole.WRITABLE },
|
|
510
|
+
{ address: token0Mint, role: AccountRole.READONLY },
|
|
511
|
+
{ address: token1Mint, role: AccountRole.READONLY },
|
|
512
|
+
{ address: user0, role: AccountRole.WRITABLE },
|
|
513
|
+
{ address: user1, role: AccountRole.WRITABLE },
|
|
514
|
+
{ address: tokenProgram, role: AccountRole.READONLY }
|
|
472
515
|
];
|
|
473
516
|
const data = encodeInstructionData(
|
|
474
517
|
INSTRUCTION_DISCRIMINATORS.collectFees,
|
|
@@ -510,7 +553,7 @@ async function fetchPool(rpc, address, config) {
|
|
|
510
553
|
return decodePool(base64ToBytes(response.value.data[0]));
|
|
511
554
|
}
|
|
512
555
|
async function fetchAllPools(rpc, config) {
|
|
513
|
-
const programId = config?.programId ??
|
|
556
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
514
557
|
const discriminatorFilter = {
|
|
515
558
|
memcmp: {
|
|
516
559
|
offset: 0n,
|
|
@@ -539,7 +582,7 @@ async function fetchAllPools(rpc, config) {
|
|
|
539
582
|
return pools;
|
|
540
583
|
}
|
|
541
584
|
async function getPoolByMints(rpc, mint0, mint1, config) {
|
|
542
|
-
const programId = config?.programId ??
|
|
585
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
543
586
|
const [poolAddress] = await getPoolAddress(mint0, mint1, programId);
|
|
544
587
|
const pool = await fetchPool(rpc, poolAddress, config);
|
|
545
588
|
if (!pool) {
|
|
@@ -567,7 +610,7 @@ async function poolExists(rpc, mint0, mint1, config) {
|
|
|
567
610
|
const result = await getPoolByMints(rpc, mint0, mint1, config);
|
|
568
611
|
return result !== null;
|
|
569
612
|
}
|
|
570
|
-
async function getPoolAddressFromMints(mint0, mint1, programId =
|
|
613
|
+
async function getPoolAddressFromMints(mint0, mint1, programId = CPMM_PROGRAM_ID) {
|
|
571
614
|
const [token0, token1] = sortMints(mint0, mint1);
|
|
572
615
|
const [poolAddress] = await getPoolAddress(mint0, mint1, programId);
|
|
573
616
|
return {
|
|
@@ -617,7 +660,7 @@ async function fetchPosition(rpc, address, config) {
|
|
|
617
660
|
return decodePosition(base64ToBytes2(response.value.data[0]));
|
|
618
661
|
}
|
|
619
662
|
async function fetchUserPositions(rpc, owner, pool, config) {
|
|
620
|
-
const programId = config?.programId ??
|
|
663
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
621
664
|
const filters = [
|
|
622
665
|
// Discriminator filter (first 8 bytes)
|
|
623
666
|
{
|
|
@@ -668,7 +711,7 @@ async function fetchUserPositions(rpc, owner, pool, config) {
|
|
|
668
711
|
return positions;
|
|
669
712
|
}
|
|
670
713
|
async function fetchPoolPositions(rpc, pool, config) {
|
|
671
|
-
const programId = config?.programId ??
|
|
714
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
672
715
|
const filters = [
|
|
673
716
|
// Discriminator filter
|
|
674
717
|
{
|
|
@@ -736,7 +779,7 @@ function getPositionValue(pool, position) {
|
|
|
736
779
|
};
|
|
737
780
|
}
|
|
738
781
|
async function fetchPositionByParams(rpc, pool, owner, positionId, config) {
|
|
739
|
-
const programId = config?.programId ??
|
|
782
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
740
783
|
const [address] = await getPositionAddress(
|
|
741
784
|
pool,
|
|
742
785
|
owner,
|
|
@@ -752,7 +795,7 @@ async function fetchPositionByParams(rpc, pool, owner, positionId, config) {
|
|
|
752
795
|
account: position
|
|
753
796
|
};
|
|
754
797
|
}
|
|
755
|
-
async function getPositionAddressFromParams(pool, owner, positionId, programId =
|
|
798
|
+
async function getPositionAddressFromParams(pool, owner, positionId, programId = CPMM_PROGRAM_ID) {
|
|
756
799
|
const [address] = await getPositionAddress(
|
|
757
800
|
pool,
|
|
758
801
|
owner,
|
|
@@ -804,7 +847,7 @@ async function fetchOracle(rpc, address, config) {
|
|
|
804
847
|
return decodeOracleState(base64ToBytes3(response.value.data[0]));
|
|
805
848
|
}
|
|
806
849
|
async function getOracleForPool(rpc, pool, config) {
|
|
807
|
-
const programId = config?.programId ??
|
|
850
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
808
851
|
const [oracleAddress] = await getOracleAddress(pool, programId);
|
|
809
852
|
const oracle = await fetchOracle(rpc, oracleAddress, config);
|
|
810
853
|
if (!oracle) {
|
|
@@ -815,7 +858,7 @@ async function getOracleForPool(rpc, pool, config) {
|
|
|
815
858
|
account: oracle
|
|
816
859
|
};
|
|
817
860
|
}
|
|
818
|
-
async function getOracleAddressFromPool(pool, programId =
|
|
861
|
+
async function getOracleAddressFromPool(pool, programId = CPMM_PROGRAM_ID) {
|
|
819
862
|
const [address] = await getOracleAddress(pool, programId);
|
|
820
863
|
return address;
|
|
821
864
|
}
|
|
@@ -939,7 +982,7 @@ function getOracleBufferStats(oracle) {
|
|
|
939
982
|
};
|
|
940
983
|
}
|
|
941
984
|
async function fetchOraclesBatch(rpc, pools, config) {
|
|
942
|
-
const programId = config?.programId ??
|
|
985
|
+
const programId = config?.programId ?? CPMM_PROGRAM_ID;
|
|
943
986
|
const oracles = /* @__PURE__ */ new Map();
|
|
944
987
|
const oracleAddresses = await Promise.all(
|
|
945
988
|
pools.map((pool) => getOracleAddress(pool, programId))
|
|
@@ -969,6 +1012,6 @@ function comparePoolAndOraclePrices(pool, oracle) {
|
|
|
969
1012
|
};
|
|
970
1013
|
}
|
|
971
1014
|
|
|
972
|
-
export { MAX_FEE_AMOUNT, calculateAccruedFees, calculateTwap, calculateTwapNumber, ceilDiv, collectProtocolFeesArgsCodec, comparePoolAndOraclePrices, computePrice0Q64, computePrice1Q64, consultTwap, createCollectFeesInstruction, createPositionArgsCodec, decodeAmmConfig, decodeOracleState, decodePool, decodePosition, encodeInstructionData, fetchAllPools, fetchOracle, fetchOraclesBatch, fetchPool, fetchPoolPositions, fetchPoolsBatch, fetchPosition, fetchPositionByParams, fetchPositionsBatch, fetchUserPositions, filterActivePositions, filterPoolsByMint, getAddLiquidityQuote, getK, getOracleAddressFromPool, getOracleAge, getOracleBufferStats, getOracleDeviation, getOracleForPool, getOracleSpotPrices, getPendingFees, getPoolAddressFromMints, getPoolByMints, getPositionAddressFromParams, getPositionValue, getRemoveLiquidityQuote, getSpotPrice0, getSpotPrice1, getSwapQuote, getSwapQuoteExactOut, getTvl, initializeConfigArgsCodec, initializeOracleArgsCodec, initializePoolArgsCodec, isOracleStale, isqrt, maxBigInt, minBigInt, numberToQ64, oracleConsultArgsCodec, poolExists, q64Div, q64Mul, q64ToNumber, quoteToNumeraireArgsCodec, ratioToNumber, removeLiquidityArgsCodec, setFeesArgsCodec, setRouteArgsCodec, setSentinelArgsCodec, sortPoolsByReserves, sortPositionsByShares, swapExactInArgsCodec, transferAdminArgsCodec };
|
|
973
|
-
//# sourceMappingURL=chunk-
|
|
974
|
-
//# sourceMappingURL=chunk-
|
|
1015
|
+
export { MAX_FEE_AMOUNT, addLiquidityArgsCodec, ammConfigDataCodec, calculateAccruedFees, calculateTwap, calculateTwapNumber, ceilDiv, collectFeesArgsCodec, collectProtocolFeesArgsCodec, comparePoolAndOraclePrices, computePrice0Q64, computePrice1Q64, consultTwap, createCollectFeesInstruction, createPositionArgsCodec, decodeAmmConfig, decodeOracleState, decodePool, decodePosition, encodeAddLiquidityArgs, encodeCollectFeesArgs, encodeCollectProtocolFeesArgs, encodeCreatePositionArgs, encodeInitializeConfigArgs, encodeInitializeOracleArgs, encodeInitializePoolArgs, encodeInstructionData, encodeOracleConsultArgs, encodeQuoteToNumeraireArgs, encodeRemoveLiquidityArgs, encodeSetFeesArgs, encodeSetRouteArgs, encodeSetSentinelArgs, encodeSwapExactInArgs, encodeTransferAdminArgs, fetchAllPools, fetchOracle, fetchOraclesBatch, fetchPool, fetchPoolPositions, fetchPoolsBatch, fetchPosition, fetchPositionByParams, fetchPositionsBatch, fetchUserPositions, filterActivePositions, filterPoolsByMint, getAddLiquidityQuote, getK, getOracleAddressFromPool, getOracleAge, getOracleBufferStats, getOracleDeviation, getOracleForPool, getOracleSpotPrices, getPendingFees, getPoolAddressFromMints, getPoolByMints, getPositionAddressFromParams, getPositionValue, getRemoveLiquidityQuote, getSpotPrice0, getSpotPrice1, getSwapQuote, getSwapQuoteExactOut, getTvl, initializeConfigArgsCodec, initializeOracleArgsCodec, initializePoolArgsCodec, isOracleStale, isqrt, maxBigInt, minBigInt, numberToQ64, observationCodec, oracleConsultArgsCodec, oracleStateDataCodec, poolDataCodec, poolExists, positionDataCodec, q64Div, q64Mul, q64ToNumber, quoteToNumeraireArgsCodec, ratioToNumber, removeLiquidityArgsCodec, setFeesArgsCodec, setRouteArgsCodec, setSentinelArgsCodec, sortPoolsByReserves, sortPositionsByShares, swapExactInArgsCodec, transferAdminArgsCodec };
|
|
1016
|
+
//# sourceMappingURL=chunk-BSHIMMA4.js.map
|
|
1017
|
+
//# sourceMappingURL=chunk-BSHIMMA4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/solana/core/codecs.ts","../src/solana/core/math.ts","../src/solana/instructions/collectFees.ts","../src/solana/client/pool.ts","../src/solana/client/position.ts","../src/solana/client/oracle.ts"],"names":["sharesOut","bytesToBase64","base64ToBytes"],"mappings":"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","file":"chunk-BSHIMMA4.js","sourcesContent":["/**\n * Borsh serialization/deserialization for CPMM accounts and instructions\n *\n * This module provides encoding/decoding utilities for program accounts\n * and instruction data using Borsh-compatible binary formats.\n */\n\nimport { getAddressCodec, type Address } from '@solana/kit';\nimport type { ReadonlyUint8Array } from '@solana/kit';\nimport {\n fixCodecSize,\n getArrayCodec,\n getBooleanCodec,\n getBytesCodec,\n getConstantDecoder,\n getHiddenPrefixDecoder,\n getOptionCodec,\n getStructCodec,\n getU8Codec,\n getU16Codec,\n getU32Codec,\n getU64Codec,\n getU128Codec,\n mergeBytes,\n transformCodec,\n unwrapOption,\n type Codec,\n} from '@solana/kit';\nimport {\n MAX_ORACLE_OBSERVATIONS,\n MAX_SENTINEL_ALLOWLIST,\n ACCOUNT_DISCRIMINATORS,\n} from './constants.js';\nimport type {\n AmmConfig,\n Pool,\n Position,\n OracleState,\n Observation,\n SwapExactInArgs,\n AddLiquidityArgs,\n RemoveLiquidityArgs,\n CollectFeesArgs,\n CollectProtocolFeesArgs,\n CreatePositionArgs,\n InitializeConfigArgs,\n InitializePoolArgs,\n InitializeOracleArgs,\n SetSentinelArgs,\n SetFeesArgs,\n SetRouteArgs,\n TransferAdminArgs,\n OracleConsultArgs,\n QuoteToNumeraireArgs,\n} from './types.js';\n\nconst addressCodec = getAddressCodec();\nconst boolCodec = getBooleanCodec();\nconst u8Codec = getU8Codec();\nconst u16Codec = getU16Codec();\nconst u32Codec = getU32Codec();\nconst u64Codec = getU64Codec();\nconst u128Codec = getU128Codec();\nconst u256Codec: Codec<bigint> = transformCodec(\n getArrayCodec(u64Codec, { size: 4 }),\n (value) => {\n if (value < 0n) {\n throw new Error('u256 cannot be negative');\n }\n if (value >> 256n !== 0n) {\n throw new Error('u256 overflow');\n }\n const mask = (1n << 64n) - 1n;\n return [\n value & mask,\n (value >> 64n) & mask,\n (value >> 128n) & mask,\n (value >> 192n) & mask,\n ];\n },\n (value) => {\n let out = 0n;\n for (let i = 0; i < 4; i += 1) {\n out |= value[i] << (64n * BigInt(i));\n }\n return out;\n },\n);\n\nconst reservedBytesCodec = transformCodec(\n fixCodecSize(getBytesCodec(), 7),\n (value: Uint8Array) => value,\n (value) => new Uint8Array(value),\n);\n\n// ============================================================================\n// Account Codecs\n// ============================================================================\n\nexport const observationCodec: Codec<Observation> = getStructCodec([\n ['timestamp', u32Codec],\n ['price0Cumulative', u256Codec],\n ['price1Cumulative', u256Codec],\n]);\n\nexport const ammConfigDataCodec: Codec<AmmConfig> = getStructCodec([\n ['admin', addressCodec],\n ['paused', boolCodec],\n ['numeraireMint', addressCodec],\n ['sentinelAllowlistLen', u8Codec],\n [\n 'sentinelAllowlist',\n getArrayCodec(addressCodec, { size: MAX_SENTINEL_ALLOWLIST }),\n ],\n ['maxSwapFeeBps', u16Codec],\n ['maxFeeSplitBps', u16Codec],\n ['maxRouteHops', u8Codec],\n ['protocolFeeEnabled', boolCodec],\n ['protocolFeeBps', u16Codec],\n ['version', u8Codec],\n ['reserved', reservedBytesCodec],\n]);\n\nexport const poolDataCodec: Codec<Pool> = getStructCodec([\n ['config', addressCodec],\n ['token0Mint', addressCodec],\n ['token1Mint', addressCodec],\n ['vault0', addressCodec],\n ['vault1', addressCodec],\n ['authority', addressCodec],\n ['bump', u8Codec],\n ['reserve0', u64Codec],\n ['reserve1', u64Codec],\n ['totalShares', u128Codec],\n ['swapFeeBps', u16Codec],\n ['feeSplitBps', u16Codec],\n ['feeGrowthGlobal0Q64', u128Codec],\n ['feeGrowthGlobal1Q64', u128Codec],\n ['feesUnclaimed0', u64Codec],\n ['feesUnclaimed1', u64Codec],\n ['sentinelProgram', addressCodec],\n ['sentinelFlags', u32Codec],\n ['numeraireMint', addressCodec],\n ['liquidityMeasureSide', u8Codec],\n ['routeNextPool', addressCodec],\n ['routeBridgeMint', addressCodec],\n ['kLast', u128Codec],\n ['protocolPosition', addressCodec],\n ['locked', u8Codec],\n ['version', u8Codec],\n ['reserved', reservedBytesCodec],\n]);\n\nexport const positionDataCodec: Codec<Position> = getStructCodec([\n ['pool', addressCodec],\n ['owner', addressCodec],\n ['positionId', u64Codec],\n ['shares', u128Codec],\n ['feeGrowthLast0Q64', u128Codec],\n ['feeGrowthLast1Q64', u128Codec],\n ['feeOwed0', u64Codec],\n ['feeOwed1', u64Codec],\n ['version', u8Codec],\n ['reserved', reservedBytesCodec],\n]);\n\nexport const oracleStateDataCodec: Codec<OracleState> = getStructCodec([\n ['pool', addressCodec],\n ['initialized', boolCodec],\n ['maxPriceChangeRatioQ64', u128Codec],\n ['lastSlot', u64Codec],\n ['truncPrice0Q64', u128Codec],\n ['truncPrice1Q64', u128Codec],\n ['deviation0Q64', u128Codec],\n ['deviation1Q64', u128Codec],\n ['price0Cumulative', u256Codec],\n ['price1Cumulative', u256Codec],\n ['lastTimestamp', u32Codec],\n ['lastObservationTimestamp', u32Codec],\n ['observationIntervalSec', u32Codec],\n ['observationIndex', u16Codec],\n [\n 'observations',\n getArrayCodec(observationCodec, { size: MAX_ORACLE_OBSERVATIONS }),\n ],\n ['version', u8Codec],\n ['reserved', reservedBytesCodec],\n]);\n\nconst ammConfigDecoder = getHiddenPrefixDecoder(ammConfigDataCodec, [\n getConstantDecoder(ACCOUNT_DISCRIMINATORS.AmmConfig),\n]);\nconst poolDecoder = getHiddenPrefixDecoder(poolDataCodec, [\n getConstantDecoder(ACCOUNT_DISCRIMINATORS.Pool),\n]);\nconst positionDecoder = getHiddenPrefixDecoder(positionDataCodec, [\n getConstantDecoder(ACCOUNT_DISCRIMINATORS.Position),\n]);\nconst oracleStateDecoder = getHiddenPrefixDecoder(oracleStateDataCodec, [\n getConstantDecoder(ACCOUNT_DISCRIMINATORS.OracleState),\n]);\n\n/**\n * Decode AmmConfig from raw account data (including discriminator)\n */\nexport function decodeAmmConfig(data: ReadonlyUint8Array): AmmConfig {\n return ammConfigDecoder.decode(data);\n}\n\n/**\n * Decode Pool from raw account data (including discriminator)\n */\nexport function decodePool(data: ReadonlyUint8Array): Pool {\n return poolDecoder.decode(data);\n}\n\n/**\n * Decode Position from raw account data (including discriminator)\n */\nexport function decodePosition(data: ReadonlyUint8Array): Position {\n return positionDecoder.decode(data);\n}\n\n/**\n * Decode OracleState from raw account data (including discriminator)\n */\nexport function decodeOracleState(data: ReadonlyUint8Array): OracleState {\n return oracleStateDecoder.decode(data);\n}\n\n// ============================================================================\n// Instruction Encoders\n// ============================================================================\n\n/**\n * Encode instruction data with discriminator prefix\n */\nexport function encodeInstructionData<T>(\n discriminator: Uint8Array,\n codec?: { encode: (args: T) => ReadonlyUint8Array | Uint8Array },\n args?: T,\n): Uint8Array {\n const encodedArgs = (() => {\n if (!codec) {\n return new Uint8Array();\n }\n if (args === undefined) {\n throw new Error('Instruction args are required for codec encoders');\n }\n return new Uint8Array(codec.encode(args));\n })();\n\n return mergeBytes([discriminator, encodedArgs]);\n}\n\ntype AddLiquidityArgsWithOracle = AddLiquidityArgs & { updateOracle?: boolean };\n\nconst optionAddressCodec: Codec<Address | null> = transformCodec(\n getOptionCodec(addressCodec, { prefix: u8Codec }),\n (value: Address | null) => value,\n (value) => unwrapOption(value),\n);\n\nexport const swapExactInArgsCodec = getStructCodec([\n ['amountIn', u64Codec],\n ['minAmountOut', u64Codec],\n ['direction', u8Codec],\n ['updateOracle', boolCodec],\n]) as Codec<SwapExactInArgs>;\n\nconst addLiquidityArgsWithOracleCodec: Codec<\n AddLiquidityArgs & { updateOracle: boolean }\n> = getStructCodec([\n ['amount0Max', u64Codec],\n ['amount1Max', u64Codec],\n ['minSharesOut', u128Codec],\n ['updateOracle', boolCodec],\n]);\n\nexport const addLiquidityArgsCodec: Codec<AddLiquidityArgsWithOracle> =\n transformCodec(\n addLiquidityArgsWithOracleCodec,\n (value: AddLiquidityArgsWithOracle) => ({\n ...value,\n updateOracle: value.updateOracle ?? false,\n }),\n (value) => value,\n );\n\nexport const removeLiquidityArgsCodec: Codec<RemoveLiquidityArgs> =\n getStructCodec([\n ['sharesIn', u128Codec],\n ['minAmount0Out', u64Codec],\n ['minAmount1Out', u64Codec],\n ['updateOracle', boolCodec],\n ]);\n\nexport const collectFeesArgsCodec: Codec<CollectFeesArgs> = getStructCodec([\n ['max0', u64Codec],\n ['max1', u64Codec],\n]);\n\nexport const collectProtocolFeesArgsCodec: Codec<CollectProtocolFeesArgs> =\n getStructCodec([\n ['max0', u64Codec],\n ['max1', u64Codec],\n ]);\n\nexport const createPositionArgsCodec: Codec<CreatePositionArgs> =\n getStructCodec([['positionId', u64Codec]]);\n\nexport const initializeConfigArgsCodec: Codec<InitializeConfigArgs> =\n getStructCodec([\n ['admin', addressCodec],\n ['numeraireMint', addressCodec],\n ['maxSwapFeeBps', u16Codec],\n ['maxFeeSplitBps', u16Codec],\n ['maxRouteHops', u8Codec],\n ['protocolFeeEnabled', boolCodec],\n ['protocolFeeBps', u16Codec],\n ['sentinelAllowlist', getArrayCodec(addressCodec, { size: u32Codec })],\n ]);\n\nexport const initializePoolArgsCodec: Codec<InitializePoolArgs> =\n getStructCodec([\n ['mintA', addressCodec],\n ['mintB', addressCodec],\n ['initialSwapFeeBps', u16Codec],\n ['initialFeeSplitBps', u16Codec],\n ['liquidityMeasureSide', u8Codec],\n ['numeraireMintOverride', optionAddressCodec],\n ]);\n\nexport const initializeOracleArgsCodec: Codec<InitializeOracleArgs> =\n getStructCodec([\n ['maxPriceChangeRatioQ64', u128Codec],\n ['observationIntervalSec', u32Codec],\n ['numObservations', u16Codec],\n ]);\n\nexport const setSentinelArgsCodec: Codec<SetSentinelArgs> = getStructCodec([\n ['sentinelProgram', addressCodec],\n ['sentinelFlags', u32Codec],\n]);\n\nexport const setFeesArgsCodec: Codec<SetFeesArgs> = getStructCodec([\n ['swapFeeBps', u16Codec],\n ['feeSplitBps', u16Codec],\n]);\n\nexport const setRouteArgsCodec: Codec<SetRouteArgs> = getStructCodec([\n ['routeNextPool', addressCodec],\n ['routeBridgeMint', addressCodec],\n]);\n\nexport const transferAdminArgsCodec: Codec<TransferAdminArgs> = getStructCodec([\n ['newAdmin', addressCodec],\n]);\n\nexport const oracleConsultArgsCodec: Codec<OracleConsultArgs> = getStructCodec([\n ['windowSeconds', u32Codec],\n]);\n\nexport const quoteToNumeraireArgsCodec: Codec<QuoteToNumeraireArgs> =\n getStructCodec([\n ['amount', u128Codec],\n ['side', u8Codec],\n ['maxHops', u8Codec],\n ['useTwap', boolCodec],\n ['windowSeconds', u32Codec],\n ]);\n\n/** Encode SwapExactIn args */\nexport function encodeSwapExactInArgs(args: SwapExactInArgs): Uint8Array {\n return new Uint8Array(swapExactInArgsCodec.encode(args));\n}\n\n/** Encode AddLiquidity args */\nexport function encodeAddLiquidityArgs(\n args: AddLiquidityArgsWithOracle,\n): Uint8Array {\n return new Uint8Array(addLiquidityArgsCodec.encode(args));\n}\n\n/** Encode RemoveLiquidity args */\nexport function encodeRemoveLiquidityArgs(\n args: RemoveLiquidityArgs,\n): Uint8Array {\n return new Uint8Array(removeLiquidityArgsCodec.encode(args));\n}\n\n/** Encode CollectFees args */\nexport function encodeCollectFeesArgs(args: CollectFeesArgs): Uint8Array {\n return new Uint8Array(collectFeesArgsCodec.encode(args));\n}\n\n/** Encode CollectProtocolFees args */\nexport function encodeCollectProtocolFeesArgs(\n args: CollectProtocolFeesArgs,\n): Uint8Array {\n return new Uint8Array(collectProtocolFeesArgsCodec.encode(args));\n}\n\n/** Encode CreatePosition args */\nexport function encodeCreatePositionArgs(args: CreatePositionArgs): Uint8Array {\n return new Uint8Array(createPositionArgsCodec.encode(args));\n}\n\n/** Encode InitializeConfig args */\nexport function encodeInitializeConfigArgs(\n args: InitializeConfigArgs,\n): Uint8Array {\n return new Uint8Array(initializeConfigArgsCodec.encode(args));\n}\n\n/** Encode InitializePool args */\nexport function encodeInitializePoolArgs(args: InitializePoolArgs): Uint8Array {\n return new Uint8Array(initializePoolArgsCodec.encode(args));\n}\n\n/** Encode InitializeOracle args */\nexport function encodeInitializeOracleArgs(\n args: InitializeOracleArgs,\n): Uint8Array {\n return new Uint8Array(initializeOracleArgsCodec.encode(args));\n}\n\n/** Encode SetSentinel args */\nexport function encodeSetSentinelArgs(args: SetSentinelArgs): Uint8Array {\n return new Uint8Array(setSentinelArgsCodec.encode(args));\n}\n\n/** Encode SetFees args */\nexport function encodeSetFeesArgs(args: SetFeesArgs): Uint8Array {\n return new Uint8Array(setFeesArgsCodec.encode(args));\n}\n\n/** Encode SetRoute args */\nexport function encodeSetRouteArgs(args: SetRouteArgs): Uint8Array {\n return new Uint8Array(setRouteArgsCodec.encode(args));\n}\n\n/** Encode TransferAdmin args */\nexport function encodeTransferAdminArgs(args: TransferAdminArgs): Uint8Array {\n return new Uint8Array(transferAdminArgsCodec.encode(args));\n}\n\n/** Encode OracleConsult args */\nexport function encodeOracleConsultArgs(args: OracleConsultArgs): Uint8Array {\n return new Uint8Array(oracleConsultArgsCodec.encode(args));\n}\n\n/** Encode QuoteToNumeraire args */\nexport function encodeQuoteToNumeraireArgs(\n args: QuoteToNumeraireArgs,\n): Uint8Array {\n return new Uint8Array(quoteToNumeraireArgsCodec.encode(args));\n}\n","import { BPS_DENOM, Q64_ONE } from './constants.js';\nimport type {\n Pool,\n SwapQuote,\n SwapQuoteExactOut,\n AddLiquidityQuote,\n RemoveLiquidityQuote,\n SwapDirection,\n} from './types.js';\n\n// ============================================================================\n// Q64.64 Fixed-Point Arithmetic\n// ============================================================================\n\n/**\n * Convert a Q64.64 fixed-point number to a decimal number\n */\nexport function q64ToNumber(q64: bigint): number {\n // Split into integer and fractional parts for precision\n const intPart = q64 >> 64n;\n const fracPart = q64 & ((1n << 64n) - 1n);\n return Number(intPart) + Number(fracPart) / Number(Q64_ONE);\n}\n\n/**\n * Convert a decimal number to Q64.64 fixed-point\n */\nexport function numberToQ64(n: number): bigint {\n const intPart = Math.floor(n);\n const fracPart = n - intPart;\n return (\n (BigInt(intPart) << 64n) + BigInt(Math.round(fracPart * Number(Q64_ONE)))\n );\n}\n\n/**\n * Multiply two Q64.64 numbers, returning Q64.64 result\n */\nexport function q64Mul(a: bigint, b: bigint): bigint {\n return (a * b) >> 64n;\n}\n\n/**\n * Divide two Q64.64 numbers, returning Q64.64 result\n */\nexport function q64Div(a: bigint, b: bigint): bigint {\n return (a << 64n) / b;\n}\n\n/**\n * Compute spot price (reserve1/reserve0) as Q64.64\n * Price of token0 denominated in token1\n */\nexport function computePrice0Q64(reserve0: bigint, reserve1: bigint): bigint {\n if (reserve0 === 0n) return 0n;\n return (reserve1 << 64n) / reserve0;\n}\n\n/**\n * Compute spot price (reserve0/reserve1) as Q64.64\n * Price of token1 denominated in token0\n */\nexport function computePrice1Q64(reserve0: bigint, reserve1: bigint): bigint {\n if (reserve1 === 0n) return 0n;\n return (reserve0 << 64n) / reserve1;\n}\n\n// ============================================================================\n// Integer Math Helpers\n// ============================================================================\n\n/**\n * Integer square root (floor)\n */\nexport function isqrt(n: bigint): bigint {\n if (n < 0n) throw new Error('isqrt: negative input');\n if (n === 0n) return 0n;\n\n let x = n;\n let y = (x + 1n) / 2n;\n\n while (y < x) {\n x = y;\n y = (x + n / x) / 2n;\n }\n\n return x;\n}\n\n/**\n * Ceiling division: ceil(a / b)\n */\nexport function ceilDiv(a: bigint, b: bigint): bigint {\n return (a + b - 1n) / b;\n}\n\n/**\n * Minimum of two bigints\n */\nexport function minBigInt(a: bigint, b: bigint): bigint {\n return a < b ? a : b;\n}\n\n/**\n * Maximum of two bigints\n */\nexport function maxBigInt(a: bigint, b: bigint): bigint {\n return a > b ? a : b;\n}\n\n/**\n * Convert a ratio of two bigints to a decimal number using Q64.64 precision\n */\nexport function ratioToNumber(numerator: bigint, denominator: bigint): number {\n if (denominator === 0n) return 0;\n const q64 = (numerator << 64n) / denominator;\n return q64ToNumber(q64);\n}\n\n// ============================================================================\n// Swap Quote Calculations\n// ============================================================================\n\n/**\n * Calculate swap output and fees for exact input amount\n *\n * Fee calculation (from spec):\n * - fee_total = floor(amount_in * fee_bps / 10_000)\n * - fee_dist = floor(fee_total * split_bps / 10_000)\n * - fee_comp = fee_total - fee_dist\n * - amount_in_eff = amount_in - fee_total\n *\n * CPMM output:\n * - amount_out = floor(amount_in_eff * reserve_out / (reserve_in + amount_in_eff))\n */\nexport function getSwapQuote(\n pool: Pool,\n amountIn: bigint,\n direction: SwapDirection,\n): SwapQuote {\n if (amountIn === 0n) {\n return {\n amountOut: 0n,\n feeTotal: 0n,\n feeDist: 0n,\n feeComp: 0n,\n priceImpact: 0,\n executionPrice: 0,\n };\n }\n\n // Get reserves based on direction\n const [reserveIn, reserveOut] =\n direction === 0\n ? [pool.reserve0, pool.reserve1]\n : [pool.reserve1, pool.reserve0];\n\n if (reserveIn === 0n || reserveOut === 0n) {\n throw new Error('Pool has zero liquidity');\n }\n\n // Calculate fees\n const feeTotal = (amountIn * BigInt(pool.swapFeeBps)) / BPS_DENOM;\n const feeDist = (feeTotal * BigInt(pool.feeSplitBps)) / BPS_DENOM;\n const feeComp = feeTotal - feeDist;\n const amountInEff = amountIn - feeTotal;\n\n // CPMM output calculation\n const amountOut = (amountInEff * reserveOut) / (reserveIn + amountInEff);\n\n // Calculate price impact\n const spotPrice = ratioToNumber(reserveOut, reserveIn);\n const executionPrice = ratioToNumber(amountOut, amountIn);\n const priceImpact =\n spotPrice === 0 ? 0 : Math.abs(spotPrice - executionPrice) / spotPrice;\n\n return {\n amountOut,\n feeTotal,\n feeDist,\n feeComp,\n priceImpact,\n executionPrice,\n };\n}\n\n/**\n * Calculate input amount needed for exact output (reverse quote)\n */\nexport function getSwapQuoteExactOut(\n pool: Pool,\n amountOut: bigint,\n direction: SwapDirection,\n): SwapQuoteExactOut {\n // Get reserves based on direction\n const [reserveIn, reserveOut] =\n direction === 0\n ? [pool.reserve0, pool.reserve1]\n : [pool.reserve1, pool.reserve0];\n\n if (reserveIn === 0n || reserveOut === 0n) {\n throw new Error('Pool has zero liquidity');\n }\n\n if (amountOut >= reserveOut) {\n throw new Error('Insufficient liquidity for output amount');\n }\n\n // Reverse CPMM formula:\n // amountOut = amountInEff * reserveOut / (reserveIn + amountInEff)\n // => amountInEff = amountOut * reserveIn / (reserveOut - amountOut)\n const amountInEff = ceilDiv(amountOut * reserveIn, reserveOut - amountOut);\n\n // Reverse fee calculation:\n // amountInEff = amountIn - feeTotal = amountIn * (1 - feeBps/10000)\n // => amountIn = amountInEff * 10000 / (10000 - feeBps)\n const amountIn = ceilDiv(\n amountInEff * BPS_DENOM,\n BPS_DENOM - BigInt(pool.swapFeeBps),\n );\n const feeTotal = amountIn - amountInEff;\n\n return { amountIn, feeTotal };\n}\n\n// ============================================================================\n// Liquidity Quote Calculations\n// ============================================================================\n\n/**\n * Calculate shares and actual amounts for adding liquidity\n *\n * From spec:\n * - If initial: shares = floor_sqrt(amount0 * amount1)\n * - Else: shares = min(amount0 * totalShares / reserve0, amount1 * totalShares / reserve1)\n */\nexport function getAddLiquidityQuote(\n pool: Pool,\n amount0Max: bigint,\n amount1Max: bigint,\n): AddLiquidityQuote {\n if (pool.totalShares === 0n) {\n // Initial liquidity deposit\n const rawShares = isqrt(amount0Max * amount1Max);\n if (rawShares === 0n) {\n throw new Error('Initial liquidity too small');\n }\n const sharesOut = rawShares;\n\n return {\n sharesOut,\n amount0: amount0Max,\n amount1: amount1Max,\n poolShare: ratioToNumber(sharesOut, rawShares),\n };\n }\n\n // Existing pool - calculate proportional deposit\n if (pool.reserve0 === 0n || pool.reserve1 === 0n) {\n throw new Error('Invalid pool state: zero reserves with non-zero shares');\n }\n\n // Calculate shares for each token amount\n const shares0 = (amount0Max * pool.totalShares) / pool.reserve0;\n const shares1 = (amount1Max * pool.totalShares) / pool.reserve1;\n const sharesOut = minBigInt(shares0, shares1);\n\n // Calculate actual amounts needed for exact ratio\n const amount0 = ceilDiv(sharesOut * pool.reserve0, pool.totalShares);\n const amount1 = ceilDiv(sharesOut * pool.reserve1, pool.totalShares);\n\n // Calculate pool share after deposit\n const newTotalShares = pool.totalShares + sharesOut;\n const poolShare = ratioToNumber(sharesOut, newTotalShares);\n\n return {\n sharesOut,\n amount0,\n amount1,\n poolShare,\n };\n}\n\n/**\n * Calculate token amounts for removing liquidity\n *\n * From spec:\n * - amount0 = shares * reserve0 / totalShares\n * - amount1 = shares * reserve1 / totalShares\n */\nexport function getRemoveLiquidityQuote(\n pool: Pool,\n sharesIn: bigint,\n): RemoveLiquidityQuote {\n if (pool.totalShares === 0n) {\n throw new Error('Pool has no shares');\n }\n if (sharesIn > pool.totalShares) {\n throw new Error('Shares exceed total supply');\n }\n\n const amount0 = (sharesIn * pool.reserve0) / pool.totalShares;\n const amount1 = (sharesIn * pool.reserve1) / pool.totalShares;\n\n return { amount0, amount1 };\n}\n\n// ============================================================================\n// Fee Growth Calculations\n// ============================================================================\n\n/**\n * Calculate accrued fees for a position\n *\n * From spec:\n * - delta = pool.fee_growth_global - position.fee_growth_last\n * - owed_inc = floor(position.shares * delta / 2^64)\n */\nexport function calculateAccruedFees(\n shares: bigint,\n feeGrowthLastQ64: bigint,\n feeGrowthGlobalQ64: bigint,\n): bigint {\n const delta = feeGrowthGlobalQ64 - feeGrowthLastQ64;\n return (shares * delta) >> 64n;\n}\n\n/**\n * Calculate pending fees for a position (both tokens)\n */\nexport function getPendingFees(\n pool: Pool,\n position: {\n shares: bigint;\n feeGrowthLast0Q64: bigint;\n feeGrowthLast1Q64: bigint;\n feeOwed0: bigint;\n feeOwed1: bigint;\n },\n): { pending0: bigint; pending1: bigint } {\n const accrued0 = calculateAccruedFees(\n position.shares,\n position.feeGrowthLast0Q64,\n pool.feeGrowthGlobal0Q64,\n );\n const accrued1 = calculateAccruedFees(\n position.shares,\n position.feeGrowthLast1Q64,\n pool.feeGrowthGlobal1Q64,\n );\n\n return {\n pending0: position.feeOwed0 + accrued0,\n pending1: position.feeOwed1 + accrued1,\n };\n}\n\n// ============================================================================\n// Price Helpers\n// ============================================================================\n\n/**\n * Calculate spot price of token0 in terms of token1\n */\nexport function getSpotPrice0(pool: Pool): number {\n if (pool.reserve0 === 0n) return 0;\n return q64ToNumber(computePrice0Q64(pool.reserve0, pool.reserve1));\n}\n\n/**\n * Calculate spot price of token1 in terms of token0\n */\nexport function getSpotPrice1(pool: Pool): number {\n if (pool.reserve1 === 0n) return 0;\n return q64ToNumber(computePrice1Q64(pool.reserve0, pool.reserve1));\n}\n\n/**\n * Calculate k (constant product invariant)\n */\nexport function getK(pool: Pool): bigint {\n return pool.reserve0 * pool.reserve1;\n}\n\n/**\n * Calculate pool TVL in terms of one token\n * @param pool Pool data\n * @param side 0 = denominate in token0, 1 = denominate in token1\n */\nexport function getTvl(pool: Pool, side: SwapDirection = 0): bigint {\n if (side === 0) {\n // TVL in token0: reserve0 + (reserve1 * price1)\n // where price1 = reserve0/reserve1 (price of 1 in terms of 0)\n // = reserve0 + reserve1 * reserve0 / reserve1 = 2 * reserve0\n return 2n * pool.reserve0;\n } else {\n // TVL in token1: reserve1 + (reserve0 * price0)\n return 2n * pool.reserve1;\n }\n}\n\n// ============================================================================\n// TWAP Helpers\n// ============================================================================\n\n/**\n * Calculate TWAP price from oracle observations\n *\n * TWAP = (cumulative_end - cumulative_start) / (timestamp_end - timestamp_start)\n */\nexport function calculateTwap(\n cumulativeStart: bigint,\n cumulativeEnd: bigint,\n timestampStart: number,\n timestampEnd: number,\n): bigint {\n const dt = BigInt(timestampEnd - timestampStart);\n if (dt === 0n) return 0n;\n\n // Handle wrapping (cumulative values can wrap around)\n const cumulativeDiff =\n cumulativeEnd >= cumulativeStart\n ? cumulativeEnd - cumulativeStart\n : (1n << 256n) - cumulativeStart + cumulativeEnd;\n\n return cumulativeDiff / dt;\n}\n\n/**\n * Calculate TWAP as a decimal number\n */\nexport function calculateTwapNumber(\n cumulativeStart: bigint,\n cumulativeEnd: bigint,\n timestampStart: number,\n timestampEnd: number,\n): number {\n const twapQ64 = calculateTwap(\n cumulativeStart,\n cumulativeEnd,\n timestampStart,\n timestampEnd,\n );\n return q64ToNumber(twapQ64);\n}\n","import type { Address, Instruction, AccountMeta } from '@solana/kit';\nimport { AccountRole } from '@solana/kit';\nimport {\n CPMM_PROGRAM_ID,\n TOKEN_PROGRAM_ADDRESS,\n INSTRUCTION_DISCRIMINATORS,\n} from '../core/constants.js';\nimport type { CollectFeesArgs } from '../core/types.js';\nimport { collectFeesArgsCodec, encodeInstructionData } from '../core/codecs.js';\n\n/**\n * Accounts required for collect_fees instruction\n */\nexport interface CollectFeesAccounts {\n /** Pool account (writable) */\n pool: Address;\n /** User's position account (writable) */\n position: Address;\n /** Position owner (signer) */\n owner: Address;\n /** Pool authority PDA (read-only) */\n authority: Address;\n /** Pool vault for token0 (writable) */\n vault0: Address;\n /** Pool vault for token1 (writable) */\n vault1: Address;\n /** Token0 mint (read-only) */\n token0Mint: Address;\n /** Token1 mint (read-only) */\n token1Mint: Address;\n /** User's token0 account (writable) */\n user0: Address;\n /** User's token1 account (writable) */\n user1: Address;\n /** SPL Token program */\n tokenProgram?: Address;\n}\n\n/**\n * Create a collect_fees instruction\n *\n * Collects accrued LP fees from a position. Fees are first accrued from the global\n * fee growth, then transferred from the pool vaults to the user's token accounts.\n * You can specify max amounts to partially collect fees.\n *\n * @param accounts - Required accounts for collecting fees\n * @param args - Instruction arguments (max0, max1)\n * @param programId - Program ID (defaults to CPMM program)\n * @returns Instruction to collect fees\n *\n * @example\n * ```ts\n * // Collect all accrued fees\n * const ix = createCollectFeesInstruction(\n * {\n * pool: poolAddress,\n * position: positionAddress,\n * owner: userPublicKey,\n * authority: authorityPda,\n * vault0: vault0Address,\n * vault1: vault1Address,\n * token0Mint: mint0,\n * token1Mint: mint1,\n * user0: userToken0Account,\n * user1: userToken1Account,\n * },\n * {\n * max0: BigInt('18446744073709551615'), // u64::MAX to collect all\n * max1: BigInt('18446744073709551615'),\n * }\n * );\n * ```\n */\nexport function createCollectFeesInstruction(\n accounts: CollectFeesAccounts,\n args: CollectFeesArgs,\n programId: Address = CPMM_PROGRAM_ID,\n): Instruction {\n const {\n pool,\n position,\n owner,\n authority,\n vault0,\n vault1,\n token0Mint,\n token1Mint,\n user0,\n user1,\n tokenProgram = TOKEN_PROGRAM_ADDRESS,\n } = accounts;\n\n // Build account metas in order expected by the program\n // Order: pool, position, owner, authority, vault0, vault1,\n // token0_mint, token1_mint, user0, user1, token_program\n const keys: AccountMeta[] = [\n { address: pool, role: AccountRole.WRITABLE },\n { address: position, role: AccountRole.WRITABLE },\n { address: owner, role: AccountRole.READONLY_SIGNER },\n { address: authority, role: AccountRole.READONLY },\n { address: vault0, role: AccountRole.WRITABLE },\n { address: vault1, role: AccountRole.WRITABLE },\n { address: token0Mint, role: AccountRole.READONLY },\n { address: token1Mint, role: AccountRole.READONLY },\n { address: user0, role: AccountRole.WRITABLE },\n { address: user1, role: AccountRole.WRITABLE },\n { address: tokenProgram, role: AccountRole.READONLY },\n ];\n\n const data = encodeInstructionData(\n INSTRUCTION_DISCRIMINATORS.collectFees,\n collectFeesArgsCodec,\n args,\n );\n\n return {\n programAddress: programId,\n accounts: keys,\n data,\n };\n}\n\n/**\n * Convenience constant for collecting all fees (u64::MAX)\n */\nexport const MAX_FEE_AMOUNT = BigInt('18446744073709551615');\n","/**\n * Pool fetching and utility functions for the CPMM SDK\n */\n\nimport type { Address } from '@solana/kit';\nimport type { Rpc, GetAccountInfoApi } from '@solana/kit';\nimport type { Base64EncodedBytes } from '@solana/kit';\nimport type { GetProgramAccountsRpc } from '../core/rpc.js';\nimport type { Pool } from '../core/types.js';\nimport { decodePool } from '../core/codecs.js';\nimport { CPMM_PROGRAM_ID, ACCOUNT_DISCRIMINATORS } from '../core/constants.js';\nimport { getPoolAddress, sortMints } from '../core/pda.js';\n\n// Browser-compatible base64 encoding/decoding utilities\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Configuration for fetching pools\n */\nexport interface FetchPoolsConfig {\n /** Program ID (defaults to CPMM program) */\n programId?: Address;\n /** Commitment level */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Pool with its address\n */\nexport interface PoolWithAddress {\n address: Address;\n account: Pool;\n}\n\ntype ProgramAccount = Readonly<{\n pubkey: Address;\n account: Readonly<{ data: [string, 'base64'] }>;\n}>;\n\n/**\n * Fetch and decode a single pool account\n *\n * @param rpc - Solana RPC client\n * @param address - Pool account address\n * @param config - Optional configuration\n * @returns Decoded pool data or null if not found\n *\n * @example\n * ```ts\n * const pool = await fetchPool(rpc, poolAddress);\n * if (pool) {\n * console.log(`Pool reserves: ${pool.reserve0} / ${pool.reserve1}`);\n * }\n * ```\n */\nexport async function fetchPool(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address,\n config?: FetchPoolsConfig,\n): Promise<Pool | null> {\n const response = await rpc\n .getAccountInfo(address, {\n encoding: 'base64',\n commitment: config?.commitment,\n })\n .send();\n\n if (!response.value) {\n return null;\n }\n\n return decodePool(base64ToBytes(response.value.data[0]));\n}\n\n/**\n * Fetch all pool accounts for the CPMM program\n *\n * Uses getProgramAccounts with a discriminator filter for efficiency.\n *\n * @param rpc - Solana RPC client\n * @param config - Optional configuration\n * @returns Array of pools with their addresses\n *\n * @example\n * ```ts\n * const pools = await fetchAllPools(rpc);\n * console.log(`Found ${pools.length} pools`);\n * for (const { address, account } of pools) {\n * console.log(`Pool ${address}: ${account.token0Mint} / ${account.token1Mint}`);\n * }\n * ```\n */\nexport async function fetchAllPools(\n rpc: GetProgramAccountsRpc,\n config?: FetchPoolsConfig,\n): Promise<PoolWithAddress[]> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n\n // Filter by Pool discriminator (first 8 bytes)\n const discriminatorFilter = {\n memcmp: {\n offset: 0n,\n bytes: bytesToBase64(ACCOUNT_DISCRIMINATORS.Pool) as Base64EncodedBytes,\n encoding: 'base64' as const,\n },\n };\n\n const response = (await rpc\n .getProgramAccounts(programId, {\n encoding: 'base64',\n commitment: config?.commitment,\n filters: [discriminatorFilter],\n })\n .send()) as unknown;\n\n const accounts = (\n Array.isArray(response)\n ? response\n : (response as { value: ProgramAccount[] }).value\n ) as ProgramAccount[];\n\n const pools: PoolWithAddress[] = [];\n\n for (const account of accounts) {\n try {\n const pool = decodePool(base64ToBytes(account.account.data[0]));\n pools.push({\n address: account.pubkey,\n account: pool,\n });\n } catch {\n // Skip accounts that fail to decode (shouldn't happen with proper filter)\n console.warn(`Failed to decode pool account: ${account.pubkey}`);\n }\n }\n\n return pools;\n}\n\n/**\n * Find a pool by its token pair mints\n *\n * Derives the pool PDA from the mints (automatically sorted) and fetches it.\n *\n * @param rpc - Solana RPC client\n * @param mint0 - First token mint\n * @param mint1 - Second token mint\n * @param config - Optional configuration\n * @returns Pool data with address, or null if not found\n *\n * @example\n * ```ts\n * const result = await getPoolByMints(rpc, usdcMint, wsolMint);\n * if (result) {\n * console.log(`Found pool at ${result.address}`);\n * console.log(`Swap fee: ${result.account.swapFeeBps} bps`);\n * }\n * ```\n */\nexport async function getPoolByMints(\n rpc: Rpc<GetAccountInfoApi>,\n mint0: Address,\n mint1: Address,\n config?: FetchPoolsConfig,\n): Promise<PoolWithAddress | null> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n\n // Derive pool address (mints are sorted internally)\n const [poolAddress] = await getPoolAddress(mint0, mint1, programId);\n\n const pool = await fetchPool(rpc, poolAddress, config);\n\n if (!pool) {\n return null;\n }\n\n return {\n address: poolAddress,\n account: pool,\n };\n}\n\n/**\n * Get multiple pools by their addresses in a single batch request\n *\n * @param rpc - Solana RPC client\n * @param addresses - Array of pool addresses to fetch\n * @param config - Optional configuration\n * @returns Map of address to pool (missing pools are not included)\n *\n * @example\n * ```ts\n * const poolMap = await fetchPoolsBatch(rpc, [pool1, pool2, pool3]);\n * for (const [addr, pool] of poolMap) {\n * console.log(`Pool ${addr}: TVL = ${pool.reserve0 + pool.reserve1}`);\n * }\n * ```\n */\nexport async function fetchPoolsBatch(\n rpc: Rpc<GetAccountInfoApi>,\n addresses: Address[],\n config?: FetchPoolsConfig,\n): Promise<Map<Address, Pool>> {\n const pools = new Map<Address, Pool>();\n\n // Fetch all in parallel\n const results = await Promise.all(\n addresses.map((addr) => fetchPool(rpc, addr, config)),\n );\n\n for (let i = 0; i < addresses.length; i++) {\n const pool = results[i];\n if (pool) {\n pools.set(addresses[i], pool);\n }\n }\n\n return pools;\n}\n\n/**\n * Check if a pool exists for a token pair\n *\n * @param rpc - Solana RPC client\n * @param mint0 - First token mint\n * @param mint1 - Second token mint\n * @param config - Optional configuration\n * @returns true if pool exists, false otherwise\n */\nexport async function poolExists(\n rpc: Rpc<GetAccountInfoApi>,\n mint0: Address,\n mint1: Address,\n config?: FetchPoolsConfig,\n): Promise<boolean> {\n const result = await getPoolByMints(rpc, mint0, mint1, config);\n return result !== null;\n}\n\n/**\n * Get the pool address for a token pair without fetching\n *\n * @param mint0 - First token mint\n * @param mint1 - Second token mint\n * @param programId - Program ID (defaults to CPMM program)\n * @returns Pool address and sorted mints\n */\nexport async function getPoolAddressFromMints(\n mint0: Address,\n mint1: Address,\n programId: Address = CPMM_PROGRAM_ID,\n): Promise<{\n poolAddress: Address;\n token0: Address;\n token1: Address;\n}> {\n const [token0, token1] = sortMints(mint0, mint1);\n const [poolAddress] = await getPoolAddress(mint0, mint1, programId);\n\n return {\n poolAddress,\n token0,\n token1,\n };\n}\n\n/**\n * Filter pools by a specific token mint\n *\n * @param pools - Array of pools to filter\n * @param mint - Token mint to filter by\n * @returns Pools that contain the specified mint\n */\nexport function filterPoolsByMint(\n pools: PoolWithAddress[],\n mint: Address,\n): PoolWithAddress[] {\n return pools.filter(\n ({ account }) => account.token0Mint === mint || account.token1Mint === mint,\n );\n}\n\n/**\n * Sort pools by total reserves (proxy for TVL)\n *\n * @param pools - Array of pools to sort\n * @param descending - Sort descending (highest first) if true\n * @returns Sorted array (does not mutate input)\n */\nexport function sortPoolsByReserves(\n pools: PoolWithAddress[],\n descending = true,\n): PoolWithAddress[] {\n return [...pools].sort((a, b) => {\n const totalA = a.account.reserve0 + a.account.reserve1;\n const totalB = b.account.reserve0 + b.account.reserve1;\n const cmp = totalA < totalB ? -1 : totalA > totalB ? 1 : 0;\n return descending ? -cmp : cmp;\n });\n}\n","/**\n * Position fetching and utility functions for the CPMM SDK\n */\n\nimport type { Address } from '@solana/kit';\nimport type { Rpc, GetAccountInfoApi } from '@solana/kit';\nimport type { GetProgramAccountsRpc } from '../core/rpc.js';\nimport type { Base58EncodedBytes, Base64EncodedBytes } from '@solana/kit';\nimport type { Position, Pool } from '../core/types.js';\nimport { decodePosition } from '../core/codecs.js';\nimport { CPMM_PROGRAM_ID, ACCOUNT_DISCRIMINATORS } from '../core/constants.js';\nimport { getPositionAddress } from '../core/pda.js';\nimport { getPendingFees, ratioToNumber } from '../core/math.js';\n\n// Browser-compatible base64 encoding/decoding utilities\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Configuration for fetching positions\n */\nexport interface FetchPositionsConfig {\n /** Program ID (defaults to CPMM program) */\n programId?: Address;\n /** Commitment level */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Position with its address\n */\nexport interface PositionWithAddress {\n address: Address;\n account: Position;\n}\n\ntype ProgramAccount = Readonly<{\n pubkey: Address;\n account: Readonly<{ data: [string, 'base64'] }>;\n}>;\n\n/**\n * Position value in underlying tokens\n */\nexport interface PositionValue {\n /** Amount of token0 the position is worth */\n amount0: bigint;\n /** Amount of token1 the position is worth */\n amount1: bigint;\n /** Pending uncollected fees in token0 */\n pendingFees0: bigint;\n /** Pending uncollected fees in token1 */\n pendingFees1: bigint;\n /** Total value in token0 (amount0 + pending0) */\n totalValue0: bigint;\n /** Total value in token1 (amount1 + pending1) */\n totalValue1: bigint;\n /** Share of pool as a decimal (0-1) */\n poolShare: number;\n}\n\n/**\n * Fetch and decode a single position account\n *\n * @param rpc - Solana RPC client\n * @param address - Position account address\n * @param config - Optional configuration\n * @returns Decoded position data or null if not found\n *\n * @example\n * ```ts\n * const position = await fetchPosition(rpc, positionAddress);\n * if (position) {\n * console.log(`Position shares: ${position.shares}`);\n * }\n * ```\n */\nexport async function fetchPosition(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address,\n config?: FetchPositionsConfig,\n): Promise<Position | null> {\n const response = await rpc\n .getAccountInfo(address, {\n encoding: 'base64',\n commitment: config?.commitment,\n })\n .send();\n\n if (!response.value) {\n return null;\n }\n\n return decodePosition(base64ToBytes(response.value.data[0]));\n}\n\n/**\n * Fetch all positions for a specific owner\n *\n * @param rpc - Solana RPC client\n * @param owner - Owner address\n * @param pool - Optional pool address to filter by\n * @param config - Optional configuration\n * @returns Array of positions with their addresses\n *\n * @example\n * ```ts\n * // Get all positions for a user\n * const allPositions = await fetchUserPositions(rpc, userWallet);\n *\n * // Get positions for a specific pool\n * const poolPositions = await fetchUserPositions(rpc, userWallet, poolAddress);\n * ```\n */\nexport async function fetchUserPositions(\n rpc: GetProgramAccountsRpc,\n owner: Address,\n pool?: Address,\n config?: FetchPositionsConfig,\n): Promise<PositionWithAddress[]> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n\n // Build filters\n const filters = [\n // Discriminator filter (first 8 bytes)\n {\n memcmp: {\n offset: 0n,\n bytes: bytesToBase64(\n ACCOUNT_DISCRIMINATORS.Position,\n ) as Base64EncodedBytes,\n encoding: 'base64' as const,\n },\n },\n // Owner filter (after 8-byte discriminator + 32-byte pool = offset 40)\n {\n memcmp: {\n offset: 40n,\n bytes: owner as unknown as Base58EncodedBytes,\n encoding: 'base58' as const,\n },\n },\n ];\n\n // Add pool filter if specified (after 8-byte discriminator = offset 8)\n if (pool) {\n filters.push({\n memcmp: {\n offset: 8n,\n bytes: pool as unknown as Base58EncodedBytes,\n encoding: 'base58' as const,\n },\n });\n }\n\n const response = (await rpc\n .getProgramAccounts(programId, {\n encoding: 'base64',\n commitment: config?.commitment,\n filters,\n })\n .send()) as unknown;\n\n const accounts = (\n Array.isArray(response)\n ? response\n : (response as { value: ProgramAccount[] }).value\n ) as ProgramAccount[];\n\n const positions: PositionWithAddress[] = [];\n\n for (const account of accounts) {\n try {\n const position = decodePosition(base64ToBytes(account.account.data[0]));\n positions.push({\n address: account.pubkey,\n account: position,\n });\n } catch {\n console.warn(`Failed to decode position account: ${account.pubkey}`);\n }\n }\n\n return positions;\n}\n\n/**\n * Fetch all positions for a specific pool\n *\n * @param rpc - Solana RPC client\n * @param pool - Pool address\n * @param config - Optional configuration\n * @returns Array of positions with their addresses\n */\nexport async function fetchPoolPositions(\n rpc: GetProgramAccountsRpc,\n pool: Address,\n config?: FetchPositionsConfig,\n): Promise<PositionWithAddress[]> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n\n const filters = [\n // Discriminator filter\n {\n memcmp: {\n offset: 0n,\n bytes: bytesToBase64(\n ACCOUNT_DISCRIMINATORS.Position,\n ) as Base64EncodedBytes,\n encoding: 'base64' as const,\n },\n },\n // Pool filter (after 8-byte discriminator = offset 8)\n {\n memcmp: {\n offset: 8n,\n bytes: pool as unknown as Base58EncodedBytes,\n encoding: 'base58' as const,\n },\n },\n ];\n\n const response = (await rpc\n .getProgramAccounts(programId, {\n encoding: 'base64',\n commitment: config?.commitment,\n filters,\n })\n .send()) as unknown;\n\n const accounts = (\n Array.isArray(response)\n ? response\n : (response as { value: ProgramAccount[] }).value\n ) as ProgramAccount[];\n\n const positions: PositionWithAddress[] = [];\n\n for (const account of accounts) {\n try {\n const position = decodePosition(base64ToBytes(account.account.data[0]));\n positions.push({\n address: account.pubkey,\n account: position,\n });\n } catch {\n console.warn(`Failed to decode position account: ${account.pubkey}`);\n }\n }\n\n return positions;\n}\n\n/**\n * Calculate the value of a position in underlying tokens\n *\n * @param pool - Pool data\n * @param position - Position data\n * @returns Position value breakdown\n *\n * @example\n * ```ts\n * const pool = await fetchPool(rpc, poolAddress);\n * const position = await fetchPosition(rpc, positionAddress);\n *\n * if (pool && position) {\n * const value = getPositionValue(pool, position);\n * console.log(`Position worth ${value.amount0} token0 + ${value.amount1} token1`);\n * console.log(`Pool share: ${(value.poolShare * 100).toFixed(2)}%`);\n * }\n * ```\n */\nexport function getPositionValue(\n pool: Pool,\n position: Position,\n): PositionValue {\n if (pool.totalShares === 0n) {\n return {\n amount0: 0n,\n amount1: 0n,\n pendingFees0: 0n,\n pendingFees1: 0n,\n totalValue0: 0n,\n totalValue1: 0n,\n poolShare: 0,\n };\n }\n\n // Calculate underlying token amounts\n const amount0 = (position.shares * pool.reserve0) / pool.totalShares;\n const amount1 = (position.shares * pool.reserve1) / pool.totalShares;\n\n // Calculate pending fees\n const { pending0, pending1 } = getPendingFees(pool, position);\n\n // Calculate pool share\n const poolShare = ratioToNumber(position.shares, pool.totalShares);\n\n return {\n amount0,\n amount1,\n pendingFees0: pending0,\n pendingFees1: pending1,\n totalValue0: amount0 + pending0,\n totalValue1: amount1 + pending1,\n poolShare,\n };\n}\n\n/**\n * Derive and fetch a position by its deterministic parameters\n *\n * @param rpc - Solana RPC client\n * @param pool - Pool address\n * @param owner - Position owner\n * @param positionId - Position ID\n * @param config - Optional configuration\n * @returns Position with address or null if not found\n */\nexport async function fetchPositionByParams(\n rpc: Rpc<GetAccountInfoApi>,\n pool: Address,\n owner: Address,\n positionId: bigint,\n config?: FetchPositionsConfig,\n): Promise<PositionWithAddress | null> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n const [address] = await getPositionAddress(\n pool,\n owner,\n positionId,\n programId,\n );\n\n const position = await fetchPosition(rpc, address, config);\n\n if (!position) {\n return null;\n }\n\n return {\n address,\n account: position,\n };\n}\n\n/**\n * Get the position address for given parameters without fetching\n *\n * @param pool - Pool address\n * @param owner - Position owner\n * @param positionId - Position ID\n * @param programId - Program ID (defaults to CPMM program)\n * @returns Position address\n */\nexport async function getPositionAddressFromParams(\n pool: Address,\n owner: Address,\n positionId: bigint,\n programId: Address = CPMM_PROGRAM_ID,\n): Promise<Address> {\n const [address] = await getPositionAddress(\n pool,\n owner,\n positionId,\n programId,\n );\n return address;\n}\n\n/**\n * Batch fetch multiple positions\n *\n * @param rpc - Solana RPC client\n * @param addresses - Array of position addresses to fetch\n * @param config - Optional configuration\n * @returns Map of address to position (missing positions are not included)\n */\nexport async function fetchPositionsBatch(\n rpc: Rpc<GetAccountInfoApi>,\n addresses: Address[],\n config?: FetchPositionsConfig,\n): Promise<Map<Address, Position>> {\n const positions = new Map<Address, Position>();\n\n const results = await Promise.all(\n addresses.map((addr) => fetchPosition(rpc, addr, config)),\n );\n\n for (let i = 0; i < addresses.length; i++) {\n const position = results[i];\n if (position) {\n positions.set(addresses[i], position);\n }\n }\n\n return positions;\n}\n\n/**\n * Filter positions with non-zero shares\n *\n * @param positions - Array of positions to filter\n * @returns Positions with shares > 0\n */\nexport function filterActivePositions(\n positions: PositionWithAddress[],\n): PositionWithAddress[] {\n return positions.filter(({ account }) => account.shares > 0n);\n}\n\n/**\n * Sort positions by share amount\n *\n * @param positions - Array of positions to sort\n * @param descending - Sort descending (largest first) if true\n * @returns Sorted array (does not mutate input)\n */\nexport function sortPositionsByShares(\n positions: PositionWithAddress[],\n descending = true,\n): PositionWithAddress[] {\n return [...positions].sort((a, b) => {\n const cmp =\n a.account.shares < b.account.shares\n ? -1\n : a.account.shares > b.account.shares\n ? 1\n : 0;\n return descending ? -cmp : cmp;\n });\n}\n","/**\n * Oracle fetching and TWAP utility functions for the CPMM SDK\n */\n\nimport type { Address } from '@solana/kit';\nimport type { Rpc, GetAccountInfoApi } from '@solana/kit';\nimport type { OracleState, TwapResult, Pool } from '../core/types.js';\nimport { decodeOracleState } from '../core/codecs.js';\nimport { CPMM_PROGRAM_ID } from '../core/constants.js';\nimport { getOracleAddress } from '../core/pda.js';\nimport { q64ToNumber } from '../core/math.js';\n\n// Browser-compatible base64 decoding\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Configuration for fetching oracles\n */\nexport interface FetchOracleConfig {\n /** Program ID (defaults to CPMM program) */\n programId?: Address;\n /** Commitment level */\n commitment?: 'processed' | 'confirmed' | 'finalized';\n}\n\n/**\n * Oracle with its address\n */\nexport interface OracleWithAddress {\n address: Address;\n account: OracleState;\n}\n\n/**\n * Fetch and decode an oracle state account\n *\n * @param rpc - Solana RPC client\n * @param address - Oracle account address\n * @param config - Optional configuration\n * @returns Decoded oracle state or null if not found\n *\n * @example\n * ```ts\n * const oracle = await fetchOracle(rpc, oracleAddress);\n * if (oracle) {\n * console.log(`Oracle initialized: ${oracle.initialized}`);\n * console.log(`Last update: ${oracle.lastTimestamp}`);\n * }\n * ```\n */\nexport async function fetchOracle(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address,\n config?: FetchOracleConfig,\n): Promise<OracleState | null> {\n const response = await rpc\n .getAccountInfo(address, {\n encoding: 'base64',\n commitment: config?.commitment,\n })\n .send();\n\n if (!response.value) {\n return null;\n }\n\n return decodeOracleState(base64ToBytes(response.value.data[0]));\n}\n\n/**\n * Get the oracle for a specific pool\n *\n * Derives the oracle PDA from the pool address and fetches it.\n *\n * @param rpc - Solana RPC client\n * @param pool - Pool address\n * @param config - Optional configuration\n * @returns Oracle data with address, or null if not found/initialized\n *\n * @example\n * ```ts\n * const result = await getOracleForPool(rpc, poolAddress);\n * if (result) {\n * console.log(`Oracle at ${result.address}`);\n * const twap = consultTwap(result.account, 300); // 5-minute TWAP\n * console.log(`TWAP price: ${twap.price0}`);\n * }\n * ```\n */\nexport async function getOracleForPool(\n rpc: Rpc<GetAccountInfoApi>,\n pool: Address,\n config?: FetchOracleConfig,\n): Promise<OracleWithAddress | null> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n const [oracleAddress] = await getOracleAddress(pool, programId);\n\n const oracle = await fetchOracle(rpc, oracleAddress, config);\n\n if (!oracle) {\n return null;\n }\n\n return {\n address: oracleAddress,\n account: oracle,\n };\n}\n\n/**\n * Get the oracle address for a pool without fetching\n *\n * @param pool - Pool address\n * @param programId - Program ID (defaults to CPMM program)\n * @returns Oracle address\n */\nexport async function getOracleAddressFromPool(\n pool: Address,\n programId: Address = CPMM_PROGRAM_ID,\n): Promise<Address> {\n const [address] = await getOracleAddress(pool, programId);\n return address;\n}\n\n/**\n * Calculate TWAP price from oracle observations\n *\n * Finds the appropriate observations in the circular buffer and computes\n * the time-weighted average price over the specified window.\n *\n * @param oracle - Oracle state data\n * @param windowSeconds - TWAP window in seconds\n * @param currentTimestamp - Optional override for current time (seconds)\n * @returns TWAP prices for both directions, or null if insufficient data\n *\n * @example\n * ```ts\n * const oracle = await fetchOracle(rpc, oracleAddress);\n * if (oracle && oracle.initialized) {\n * // Get 5-minute TWAP\n * const twap = consultTwap(oracle, 300);\n * if (twap) {\n * console.log(`Token0 price: ${twap.price0} token1 per token0`);\n * console.log(`Token1 price: ${twap.price1} token0 per token1`);\n * }\n * }\n * ```\n */\nexport function consultTwap(\n oracle: OracleState,\n windowSeconds: number,\n currentTimestamp?: number,\n): TwapResult | null {\n if (!oracle.initialized || oracle.lastTimestamp === 0) {\n return null;\n }\n\n const nowTs = Math.max(0, Math.floor(currentTimestamp ?? Date.now() / 1000));\n const dtSinceLast = Math.max(0, nowTs - oracle.lastTimestamp);\n\n const cum0Now =\n oracle.price0Cumulative + oracle.truncPrice0Q64 * BigInt(dtSinceLast);\n const cum1Now =\n oracle.price1Cumulative + oracle.truncPrice1Q64 * BigInt(dtSinceLast);\n\n if (windowSeconds === 0) {\n return {\n price0Q64: oracle.truncPrice0Q64,\n price1Q64: oracle.truncPrice1Q64,\n price0: q64ToNumber(oracle.truncPrice0Q64),\n price1: q64ToNumber(oracle.truncPrice1Q64),\n };\n }\n\n const targetTs = Math.max(0, nowTs - windowSeconds);\n const sample = selectSample(oracle, targetTs);\n if (!sample) {\n return null;\n }\n\n const dt = Math.max(0, nowTs - sample.timestamp);\n if (dt === 0) {\n return null;\n }\n\n const price0Q64 = (cum0Now - sample.price0Cumulative) / BigInt(dt);\n const price1Q64 = (cum1Now - sample.price1Cumulative) / BigInt(dt);\n\n return {\n price0Q64,\n price1Q64,\n price0: q64ToNumber(price0Q64),\n price1: q64ToNumber(price1Q64),\n };\n}\n\nfunction selectSample(\n oracle: OracleState,\n targetTimestamp: number,\n): OracleState['observations'][number] | null {\n let best: OracleState['observations'][number] | null = null;\n const base = {\n timestamp: oracle.lastTimestamp,\n price0Cumulative: oracle.price0Cumulative,\n price1Cumulative: oracle.price1Cumulative,\n };\n\n if (base.timestamp !== 0 && base.timestamp <= targetTimestamp) {\n best = base;\n }\n\n for (const obs of oracle.observations) {\n if (obs.timestamp === 0) {\n continue;\n }\n if (obs.timestamp <= targetTimestamp) {\n if (!best || obs.timestamp > best.timestamp) {\n best = obs;\n }\n }\n }\n\n if (best) {\n return best;\n }\n\n let oldest: OracleState['observations'][number] | null =\n base.timestamp !== 0 ? base : null;\n for (const obs of oracle.observations) {\n if (obs.timestamp === 0) {\n continue;\n }\n if (!oldest || obs.timestamp < oldest.timestamp) {\n oldest = obs;\n }\n }\n\n return oldest;\n}\n\n/**\n * Get the current spot prices from oracle\n *\n * Uses the truncated (manipulation-resistant) prices stored in the oracle.\n *\n * @param oracle - Oracle state data\n * @returns Current truncated prices\n */\nexport function getOracleSpotPrices(oracle: OracleState): {\n price0Q64: bigint;\n price1Q64: bigint;\n price0: number;\n price1: number;\n} {\n return {\n price0Q64: oracle.truncPrice0Q64,\n price1Q64: oracle.truncPrice1Q64,\n price0: q64ToNumber(oracle.truncPrice0Q64),\n price1: q64ToNumber(oracle.truncPrice1Q64),\n };\n}\n\n/**\n * Get the price deviation metrics from oracle\n *\n * Deviation indicates how much the spot price has moved from the truncated price.\n * High deviation may indicate price manipulation or rapid market movement.\n *\n * @param oracle - Oracle state data\n * @returns Deviation values for both price directions\n */\nexport function getOracleDeviation(oracle: OracleState): {\n deviation0Q64: bigint;\n deviation1Q64: bigint;\n deviation0: number;\n deviation1: number;\n} {\n return {\n deviation0Q64: oracle.deviation0Q64,\n deviation1Q64: oracle.deviation1Q64,\n deviation0: q64ToNumber(oracle.deviation0Q64),\n deviation1: q64ToNumber(oracle.deviation1Q64),\n };\n}\n\n/**\n * Calculate the age of the oracle (time since last update)\n *\n * @param oracle - Oracle state data\n * @param currentTimestamp - Current timestamp (defaults to Date.now() / 1000)\n * @returns Age in seconds\n */\nexport function getOracleAge(\n oracle: OracleState,\n currentTimestamp?: number,\n): number {\n const now = currentTimestamp ?? Math.floor(Date.now() / 1000);\n return now - oracle.lastTimestamp;\n}\n\n/**\n * Check if oracle is stale (hasn't been updated recently)\n *\n * @param oracle - Oracle state data\n * @param maxAgeSeconds - Maximum acceptable age in seconds\n * @param currentTimestamp - Current timestamp (defaults to Date.now() / 1000)\n * @returns true if oracle is stale\n */\nexport function isOracleStale(\n oracle: OracleState,\n maxAgeSeconds: number,\n currentTimestamp?: number,\n): boolean {\n return getOracleAge(oracle, currentTimestamp) > maxAgeSeconds;\n}\n\n/**\n * Get observation buffer statistics\n *\n * @param oracle - Oracle state data\n * @returns Information about the observation buffer\n */\nexport function getOracleBufferStats(oracle: OracleState): {\n /** Total buffer capacity */\n capacity: number;\n /** Number of observations with data */\n filledCount: number;\n /** Current write index */\n currentIndex: number;\n /** Oldest observation timestamp (0 if not filled) */\n oldestTimestamp: number;\n /** Newest observation timestamp */\n newestTimestamp: number;\n /** Time span covered by observations */\n timeSpanSeconds: number;\n} {\n const observations = oracle.observations;\n const capacity = observations.length;\n const currentIndex = oracle.observationIndex;\n\n let filledCount = 0;\n let oldestTimestamp = 0;\n let newestTimestamp = 0;\n\n for (let i = 0; i < capacity; i++) {\n const obs = observations[i];\n if (obs.timestamp > 0) {\n filledCount++;\n if (oldestTimestamp === 0 || obs.timestamp < oldestTimestamp) {\n oldestTimestamp = obs.timestamp;\n }\n if (obs.timestamp > newestTimestamp) {\n newestTimestamp = obs.timestamp;\n }\n }\n }\n\n return {\n capacity,\n filledCount,\n currentIndex,\n oldestTimestamp,\n newestTimestamp,\n timeSpanSeconds:\n newestTimestamp > oldestTimestamp ? newestTimestamp - oldestTimestamp : 0,\n };\n}\n\n/**\n * Batch fetch oracles for multiple pools\n *\n * @param rpc - Solana RPC client\n * @param pools - Array of pool addresses\n * @param config - Optional configuration\n * @returns Map of pool address to oracle (missing oracles not included)\n */\nexport async function fetchOraclesBatch(\n rpc: Rpc<GetAccountInfoApi>,\n pools: Address[],\n config?: FetchOracleConfig,\n): Promise<Map<Address, OracleWithAddress>> {\n const programId = config?.programId ?? CPMM_PROGRAM_ID;\n const oracles = new Map<Address, OracleWithAddress>();\n\n // Derive all oracle addresses\n const oracleAddresses = await Promise.all(\n pools.map((pool) => getOracleAddress(pool, programId)),\n );\n\n // Fetch all oracles in parallel\n const results = await Promise.all(\n oracleAddresses.map(([addr]) => fetchOracle(rpc, addr, config)),\n );\n\n for (let i = 0; i < pools.length; i++) {\n const oracle = results[i];\n if (oracle) {\n oracles.set(pools[i], {\n address: oracleAddresses[i][0],\n account: oracle,\n });\n }\n }\n\n return oracles;\n}\n\n/**\n * Calculate price from pool reserves and compare with oracle\n *\n * Useful for detecting price discrepancies or manipulation.\n *\n * @param pool - Pool data\n * @param oracle - Oracle data\n * @returns Comparison metrics\n */\nexport function comparePoolAndOraclePrices(\n pool: Pool,\n oracle: OracleState,\n): {\n /** Spot price from pool reserves (token1 per token0) */\n poolPrice0: number;\n /** Truncated price from oracle (token1 per token0) */\n oraclePrice0: number;\n /** Difference as percentage (positive = pool > oracle) */\n divergencePct: number;\n} {\n const poolPrice0 =\n pool.reserve0 > 0n ? Number(pool.reserve1) / Number(pool.reserve0) : 0;\n\n const oraclePrice0 = q64ToNumber(oracle.truncPrice0Q64);\n\n const divergencePct =\n oraclePrice0 > 0 ? ((poolPrice0 - oraclePrice0) / oraclePrice0) * 100 : 0;\n\n return {\n poolPrice0,\n oraclePrice0,\n divergencePct,\n };\n}\n"]}
|