@w3lib/solana-batch-call 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +231 -3
  3. package/dist/approvals.d.ts +129 -0
  4. package/dist/approvals.d.ts.map +1 -0
  5. package/dist/approvals.js +221 -0
  6. package/dist/approvals.js.map +1 -0
  7. package/dist/fees.d.ts +89 -0
  8. package/dist/fees.d.ts.map +1 -0
  9. package/dist/fees.js +166 -0
  10. package/dist/fees.js.map +1 -0
  11. package/dist/layout.d.ts +2 -0
  12. package/dist/layout.d.ts.map +1 -1
  13. package/dist/layout.js +2 -2
  14. package/dist/layout.js.map +1 -1
  15. package/dist/lp.d.ts +8 -15
  16. package/dist/lp.d.ts.map +1 -1
  17. package/dist/lp.js +7 -31
  18. package/dist/lp.js.map +1 -1
  19. package/dist/names.d.ts +68 -0
  20. package/dist/names.d.ts.map +1 -0
  21. package/dist/names.js +257 -0
  22. package/dist/names.js.map +1 -0
  23. package/dist/pools.d.ts +9 -0
  24. package/dist/pools.d.ts.map +1 -0
  25. package/dist/pools.js +45 -0
  26. package/dist/pools.js.map +1 -0
  27. package/dist/portfolio.d.ts +64 -0
  28. package/dist/portfolio.d.ts.map +1 -0
  29. package/dist/portfolio.js +57 -0
  30. package/dist/portfolio.js.map +1 -0
  31. package/dist/price.d.ts +90 -0
  32. package/dist/price.d.ts.map +1 -0
  33. package/dist/price.js +287 -0
  34. package/dist/price.js.map +1 -0
  35. package/dist/risk.d.ts +84 -0
  36. package/dist/risk.d.ts.map +1 -0
  37. package/dist/risk.js +211 -0
  38. package/dist/risk.js.map +1 -0
  39. package/dist/rpc.d.ts +2 -0
  40. package/dist/rpc.d.ts.map +1 -1
  41. package/dist/rpc.js +33 -9
  42. package/dist/rpc.js.map +1 -1
  43. package/dist/subpaths/approvals.d.ts +29 -0
  44. package/dist/subpaths/approvals.d.ts.map +1 -0
  45. package/dist/subpaths/approvals.js +30 -0
  46. package/dist/subpaths/approvals.js.map +1 -0
  47. package/dist/subpaths/fees.d.ts +23 -0
  48. package/dist/subpaths/fees.d.ts.map +1 -0
  49. package/dist/subpaths/fees.js +25 -0
  50. package/dist/subpaths/fees.js.map +1 -0
  51. package/dist/subpaths/names.d.ts +37 -0
  52. package/dist/subpaths/names.d.ts.map +1 -0
  53. package/dist/subpaths/names.js +27 -0
  54. package/dist/subpaths/names.js.map +1 -0
  55. package/dist/subpaths/price.d.ts +40 -0
  56. package/dist/subpaths/price.d.ts.map +1 -0
  57. package/dist/subpaths/price.js +43 -0
  58. package/dist/subpaths/price.js.map +1 -0
  59. package/dist/subpaths/risk.d.ts +28 -0
  60. package/dist/subpaths/risk.d.ts.map +1 -0
  61. package/dist/subpaths/risk.js +30 -0
  62. package/dist/subpaths/risk.js.map +1 -0
  63. package/dist/subpaths/swap.d.ts +22 -0
  64. package/dist/subpaths/swap.d.ts.map +1 -0
  65. package/dist/subpaths/swap.js +21 -0
  66. package/dist/subpaths/swap.js.map +1 -0
  67. package/dist/subpaths/write.d.ts +1 -1
  68. package/dist/subpaths/write.d.ts.map +1 -1
  69. package/dist/subpaths/write.js +1 -1
  70. package/dist/subpaths/write.js.map +1 -1
  71. package/dist/swap/amm.d.ts +20 -0
  72. package/dist/swap/amm.d.ts.map +1 -0
  73. package/dist/swap/amm.js +77 -0
  74. package/dist/swap/amm.js.map +1 -0
  75. package/dist/swap/clmmMath.d.ts +24 -0
  76. package/dist/swap/clmmMath.d.ts.map +1 -0
  77. package/dist/swap/clmmMath.js +82 -0
  78. package/dist/swap/clmmMath.js.map +1 -0
  79. package/dist/swap/common.d.ts +68 -0
  80. package/dist/swap/common.d.ts.map +1 -0
  81. package/dist/swap/common.js +65 -0
  82. package/dist/swap/common.js.map +1 -0
  83. package/dist/swap/cpmm.d.ts +28 -0
  84. package/dist/swap/cpmm.d.ts.map +1 -0
  85. package/dist/swap/cpmm.js +113 -0
  86. package/dist/swap/cpmm.js.map +1 -0
  87. package/dist/swap/index.d.ts +145 -0
  88. package/dist/swap/index.d.ts.map +1 -0
  89. package/dist/swap/index.js +349 -0
  90. package/dist/swap/index.js.map +1 -0
  91. package/dist/swap/orca.d.ts +50 -0
  92. package/dist/swap/orca.d.ts.map +1 -0
  93. package/dist/swap/orca.js +382 -0
  94. package/dist/swap/orca.js.map +1 -0
  95. package/dist/swap/raydiumClmm.d.ts +62 -0
  96. package/dist/swap/raydiumClmm.d.ts.map +1 -0
  97. package/dist/swap/raydiumClmm.js +447 -0
  98. package/dist/swap/raydiumClmm.js.map +1 -0
  99. package/dist/tradeCheck.d.ts +45 -0
  100. package/dist/tradeCheck.d.ts.map +1 -0
  101. package/dist/tradeCheck.js +131 -0
  102. package/dist/tradeCheck.js.map +1 -0
  103. package/dist/write/instructions.d.ts +7 -0
  104. package/dist/write/instructions.d.ts.map +1 -1
  105. package/dist/write/instructions.js +24 -1
  106. package/dist/write/instructions.js.map +1 -1
  107. package/dist/write/transaction.d.ts +23 -0
  108. package/dist/write/transaction.d.ts.map +1 -1
  109. package/dist/write/transaction.js +50 -0
  110. package/dist/write/transaction.js.map +1 -1
  111. package/package.json +46 -14
  112. package/src/approvals.ts +358 -0
  113. package/src/fees.ts +259 -0
  114. package/src/layout.ts +2 -2
  115. package/src/lp.ts +8 -44
  116. package/src/names.ts +329 -0
  117. package/src/pools.ts +43 -0
  118. package/src/portfolio.ts +124 -0
  119. package/src/price.ts +366 -0
  120. package/src/risk.ts +243 -0
  121. package/src/rpc.ts +36 -9
  122. package/src/subpaths/approvals.ts +47 -0
  123. package/src/subpaths/fees.ts +41 -0
  124. package/src/subpaths/names.ts +45 -0
  125. package/src/subpaths/price.ts +62 -0
  126. package/src/subpaths/risk.ts +36 -0
  127. package/src/subpaths/swap.ts +41 -0
  128. package/src/subpaths/write.ts +2 -0
  129. package/src/swap/amm.ts +88 -0
  130. package/src/swap/clmmMath.ts +96 -0
  131. package/src/swap/common.ts +113 -0
  132. package/src/swap/cpmm.ts +132 -0
  133. package/src/swap/index.ts +467 -0
  134. package/src/swap/orca.ts +397 -0
  135. package/src/swap/raydiumClmm.ts +464 -0
  136. package/src/tradeCheck.ts +166 -0
  137. package/src/write/instructions.ts +26 -1
  138. package/src/write/transaction.ts +62 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * 集中流动性兑换一步的计算(只做按输入数量兑换),照搬 Raydium CLMM(libraries/swap_math.rs、sqrt_price_math.rs、liquidity_math.rs)
3
+ * 和 Orca Whirlpool(math/swap_math.rs、token_math.rs)。两个程序“手续费从输入扣”时的公式和取整完全相同;Raydium 另有“手续费从输出扣”的池子
4
+ */
5
+ import { U64_MAX, mulDivCeil } from './common.js';
6
+ const Q64 = 1n << 64n;
7
+ export const FEE_RATE_DENOMINATOR = 1000000n;
8
+ export class SwapMathError extends Error {
9
+ }
10
+ /** 价格从 a 到 b(任意顺序)对应的 token0 数量:L · 2^64 · (hi − lo) / (lo · hi) */
11
+ export function amount0Delta(a, b, liquidity, roundUp) {
12
+ const [lo, hi] = a < b ? [a, b] : [b, a];
13
+ if (lo === 0n)
14
+ throw new SwapMathError('zero sqrt price');
15
+ const num = (liquidity * (hi - lo)) << 64n;
16
+ const den = lo * hi;
17
+ return roundUp ? (num + den - 1n) / den : num / den;
18
+ }
19
+ /** 价格从 a 到 b 对应的 token1 数量:L · (hi − lo) / 2^64 */
20
+ export function amount1Delta(a, b, liquidity, roundUp) {
21
+ const [lo, hi] = a < b ? [a, b] : [b, a];
22
+ const p = liquidity * (hi - lo);
23
+ return roundUp ? (p + Q64 - 1n) >> 64n : p >> 64n;
24
+ }
25
+ /** 卖出 amount 后的 sqrt 价格(向不越过目标价格的方向取整):卖 token0 时价格下降,卖 token1 时上升 */
26
+ export function nextSqrtPriceFromInput(sqrtPrice, liquidity, amount, zeroForOne) {
27
+ if (liquidity === 0n)
28
+ throw new SwapMathError('zero liquidity');
29
+ if (amount === 0n)
30
+ return sqrtPrice;
31
+ if (zeroForOne) {
32
+ const num = liquidity << 64n;
33
+ const den = num + amount * sqrtPrice;
34
+ return mulDivCeil(num, sqrtPrice, den);
35
+ }
36
+ return sqrtPrice + (amount << 64n) / liquidity;
37
+ }
38
+ /**
39
+ * 一步兑换:从当前价格向目标价格,最多用 remaining 个输入。
40
+ * feeOnInput(Orca 和 Raydium 的默认):输入先按费率扣手续费;否则(Raydium fee_on):输出按费率扣
41
+ */
42
+ export function computeSwapStep(sqrtCurrent, sqrtTarget, liquidity, remaining, feeRate, zeroForOne, feeOnInput, program) {
43
+ const amountForPrice = feeOnInput ? (remaining * (FEE_RATE_DENOMINATOR - feeRate)) / FEE_RATE_DENOMINATOR : remaining;
44
+ // 走到目标价格需要的输入(向上取整)和得到的输出(向下取整);超过 u64 视为走不到
45
+ const inAtTarget = zeroForOne ? amount0Delta(sqrtTarget, sqrtCurrent, liquidity, true) : amount1Delta(sqrtCurrent, sqrtTarget, liquidity, true);
46
+ let sqrtNext;
47
+ let amountIn;
48
+ let amountOut;
49
+ const outAtTarget = () => (zeroForOne ? amount1Delta(sqrtTarget, sqrtCurrent, liquidity, false) : amount0Delta(sqrtCurrent, sqrtTarget, liquidity, false));
50
+ let reached = inAtTarget <= U64_MAX && amountForPrice >= inAtTarget;
51
+ // Raydium:目标价格处的输出超过 u64 也算走不到;Orca 照常走到目标(之后报错)
52
+ const out = reached ? outAtTarget() : 0n;
53
+ if (reached && program === 'raydium' && out > U64_MAX)
54
+ reached = false;
55
+ if (reached) {
56
+ sqrtNext = sqrtTarget;
57
+ amountIn = inAtTarget;
58
+ amountOut = out;
59
+ }
60
+ else {
61
+ sqrtNext = nextSqrtPriceFromInput(sqrtCurrent, liquidity, amountForPrice, zeroForOne);
62
+ amountIn = zeroForOne ? amount0Delta(sqrtNext, sqrtCurrent, liquidity, true) : amount1Delta(sqrtCurrent, sqrtNext, liquidity, true);
63
+ amountOut = zeroForOne ? amount1Delta(sqrtNext, sqrtCurrent, liquidity, false) : amount0Delta(sqrtCurrent, sqrtNext, liquidity, false);
64
+ }
65
+ if (amountIn > U64_MAX || amountOut > U64_MAX)
66
+ throw new SwapMathError('token amount exceeds u64');
67
+ if (zeroForOne ? sqrtNext < sqrtTarget : sqrtNext > sqrtTarget)
68
+ throw new SwapMathError('price moved past the target');
69
+ let feeAmount;
70
+ if (feeOnInput) {
71
+ feeAmount = sqrtNext !== sqrtTarget ? remaining - amountIn : mulDivCeil(amountIn, feeRate, FEE_RATE_DENOMINATOR - feeRate);
72
+ }
73
+ else {
74
+ feeAmount = mulDivCeil(amountOut, feeRate, FEE_RATE_DENOMINATOR);
75
+ amountOut -= feeAmount;
76
+ // 没走到目标价格:输入全部用掉(不足一个单位的零头归池子)
77
+ if (sqrtNext !== sqrtTarget)
78
+ amountIn = remaining;
79
+ }
80
+ return { sqrtPrice: sqrtNext, amountIn, amountOut, feeAmount };
81
+ }
82
+ //# sourceMappingURL=clmmMath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clmmMath.js","sourceRoot":"","sources":["../../src/swap/clmmMath.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { type AccountInfo } from '../layout.js';
2
+ import { Bytes } from '../lp.js';
3
+ import type { Instruction } from '../write/transaction.js';
4
+ export type SolanaSwapProtocol = 'raydium-clmm' | 'orca-whirlpool' | 'raydium-cpmm' | 'raydium-amm';
5
+ /** 报价时的链上环境:Clock sysvar 的时间(秒)和 epoch(Token-2022 转账手续费按 epoch 选配置;动态费率按时间衰减) */
6
+ export interface SwapEnv {
7
+ timestamp: bigint;
8
+ epoch: bigint;
9
+ }
10
+ export declare const CLOCK_SYSVAR_ID = "SysvarC1ock11111111111111111111111111111111";
11
+ /** Clock:slot u64、epoch_start_timestamp i64、epoch u64、leader_schedule_epoch u64、unix_timestamp i64 */
12
+ export declare function parseClock(data: Uint8Array): SwapEnv;
13
+ /** 读到的账户:address → 账户(不存在为 null);没读的为 undefined */
14
+ export type AccountGetter = (address: string) => AccountInfo | null | undefined;
15
+ /** 池子不支持本地报价 / 兑换(跳过这个池子,原因在 plan 里能看到) */
16
+ export declare class UnsupportedPool extends Error {
17
+ }
18
+ /** 报价还需要读这些账户(如兑换走得比预读的 tick 数组更远):读完后重新报价 */
19
+ export declare class NeedAccounts extends Error {
20
+ readonly addresses: string[];
21
+ constructor(addresses: string[]);
22
+ }
23
+ export declare const U64_MAX: bigint;
24
+ export declare const mulDivFloor: (a: bigint, b: bigint, d: bigint) => bigint;
25
+ export declare const mulDivCeil: (a: bigint, b: bigint, d: bigint) => bigint;
26
+ export declare function need(get: AccountGetter, address: string, what: string): AccountInfo;
27
+ /** 交易里要用的代币信息 */
28
+ export interface SwapMint {
29
+ mint: string;
30
+ program: string;
31
+ decimals: number;
32
+ /** 原始 mint 账户(算 Token-2022 转账手续费) */
33
+ account: AccountInfo;
34
+ }
35
+ /**
36
+ * 解析池子里一种代币的 mint:SPL Token / Token-2022;带转账 hook(需要额外账户)的不支持。
37
+ * 带转账手续费的支持(按当前 epoch 的费率算)
38
+ */
39
+ export declare function swapMint(mint: string, account: AccountInfo): SwapMint;
40
+ /** Token-2022 转账手续费:ceil(amount × 费率 / 10000),不超过单笔上限;SPL Token 为 0(与 Token-2022 的 calculate_epoch_fee 一致) */
41
+ export declare function transferFee(mint: SwapMint, amount: bigint, epoch: bigint): bigint;
42
+ /** 一跳的报价:用户付出 amountIn(含输入代币的转账手续费),实际收到 amountOut(已扣输出代币的转账手续费) */
43
+ export interface HopQuote {
44
+ amountIn: bigint;
45
+ amountOut: bigint;
46
+ /** 交易里要传的额外账户(tick 数组等),由各协议的 instruction 使用 */
47
+ accounts: string[];
48
+ /** 集中流动性:穿过的已初始化 tick 数、成交的限价单 tick 数(Raydium) */
49
+ crossed?: number;
50
+ orders?: number;
51
+ }
52
+ /** 一个可以兑换的池子(已解析) */
53
+ export interface SwapPool {
54
+ protocol: SolanaSwapProtocol;
55
+ address: string;
56
+ mint0: string;
57
+ mint1: string;
58
+ /** 报价要读的账户(池子账户之外):按方向(zeroForOne:卖出 mint0) */
59
+ accounts(zeroForOne: boolean): string[];
60
+ /** 本地报价(只用读到的账户,纯计算);池子不支持时抛 UnsupportedPool */
61
+ quote(get: AccountGetter, amountIn: bigint, zeroForOne: boolean, env: SwapEnv): HopQuote;
62
+ /** 兑换指令:从 input 代币账户卖出 amountIn,output 代币账户至少收到 minOut */
63
+ instruction(get: AccountGetter, owner: string, input: string, output: string, zeroForOne: boolean, quote: HopQuote, minOut: bigint): Instruction;
64
+ /** 两种代币的 mint 信息(报价后可用) */
65
+ mints(get: AccountGetter): [SwapMint, SwapMint];
66
+ }
67
+ export { Bytes };
68
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/swap/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../constants.js';
2
+ import { findExtension, parseMint, parseTransferFeeConfig } from '../layout.js';
3
+ import { Bytes } from '../lp.js';
4
+ export const CLOCK_SYSVAR_ID = 'SysvarC1ock11111111111111111111111111111111';
5
+ /** Clock:slot u64、epoch_start_timestamp i64、epoch u64、leader_schedule_epoch u64、unix_timestamp i64 */
6
+ export function parseClock(data) {
7
+ if (data.length < 40)
8
+ throw new Error('Unexpected Clock sysvar data');
9
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
10
+ return { epoch: view.getBigUint64(16, true), timestamp: view.getBigInt64(32, true) };
11
+ }
12
+ /** 池子不支持本地报价 / 兑换(跳过这个池子,原因在 plan 里能看到) */
13
+ export class UnsupportedPool extends Error {
14
+ }
15
+ /** 报价还需要读这些账户(如兑换走得比预读的 tick 数组更远):读完后重新报价 */
16
+ export class NeedAccounts extends Error {
17
+ addresses;
18
+ constructor(addresses) {
19
+ super(`Need ${addresses.length} more accounts`);
20
+ this.addresses = addresses;
21
+ }
22
+ }
23
+ export const U64_MAX = (1n << 64n) - 1n;
24
+ export const mulDivFloor = (a, b, d) => (a * b) / d;
25
+ export const mulDivCeil = (a, b, d) => (a * b + d - 1n) / d;
26
+ export function need(get, address, what) {
27
+ const account = get(address);
28
+ if (account === undefined)
29
+ throw new Error(`${what} was not loaded: ${address}`);
30
+ if (account === null)
31
+ throw new UnsupportedPool(`${what} not found: ${address}`);
32
+ return account;
33
+ }
34
+ const EXTENSION_TRANSFER_HOOK = 14;
35
+ /**
36
+ * 解析池子里一种代币的 mint:SPL Token / Token-2022;带转账 hook(需要额外账户)的不支持。
37
+ * 带转账手续费的支持(按当前 epoch 的费率算)
38
+ */
39
+ export function swapMint(mint, account) {
40
+ if (account.owner !== TOKEN_PROGRAM_ID && account.owner !== TOKEN_2022_PROGRAM_ID) {
41
+ throw new UnsupportedPool(`${mint} is not a token mint`);
42
+ }
43
+ if (account.owner === TOKEN_2022_PROGRAM_ID) {
44
+ const hook = findExtension(account.data, EXTENSION_TRANSFER_HOOK);
45
+ if (hook && hook.length >= 64 && hook.subarray(32, 64).some((b) => b !== 0)) {
46
+ throw new UnsupportedPool(`${mint} has a transfer hook, which is not supported`);
47
+ }
48
+ }
49
+ return { mint, program: account.owner, decimals: parseMint(account.data).decimals, account };
50
+ }
51
+ /** Token-2022 转账手续费:ceil(amount × 费率 / 10000),不超过单笔上限;SPL Token 为 0(与 Token-2022 的 calculate_epoch_fee 一致) */
52
+ export function transferFee(mint, amount, epoch) {
53
+ if (mint.program !== TOKEN_2022_PROGRAM_ID || amount === 0n)
54
+ return 0n;
55
+ const config = parseTransferFeeConfig(mint.account.data);
56
+ if (!config)
57
+ return 0n;
58
+ const fee = epoch >= config.newer.epoch ? config.newer : config.older;
59
+ if (fee.basisPoints === 0)
60
+ return 0n;
61
+ const raw = (amount * BigInt(fee.basisPoints) + 9999n) / 10000n;
62
+ return raw < fee.maximumFee ? raw : fee.maximumFee;
63
+ }
64
+ export { Bytes };
65
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/swap/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Raydium CPMM 的兑换:swap_base_input。报价照搬程序(raydium-cp-swap curve/calculator.rs):
3
+ * 交易费(含创建者手续费,从输入或输出扣)向上取整,恒定乘积向下取整,储备 = 金库余额 − 协议 / 基金 / 创建者手续费;输入输出的 Token-2022 转账手续费都算
4
+ */
5
+ import { type AccountInfo } from '../layout.js';
6
+ import { type SwapPool } from './common.js';
7
+ interface CpmmState {
8
+ address: string;
9
+ config: string;
10
+ vault0: string;
11
+ vault1: string;
12
+ mint0: string;
13
+ mint1: string;
14
+ observation: string;
15
+ status: number;
16
+ openTime: bigint;
17
+ reserved0: bigint;
18
+ reserved1: bigint;
19
+ creatorFeeOn: number;
20
+ creatorFeeEnabled: boolean;
21
+ }
22
+ /** PoolState:amm_config 8、vault 72 / 104、mint 168 / 200、observation 296、status 329、协议 / 基金手续费 341…、open_time 373、creator_fee_on 389、enable_creator_fee 390、创建者手续费 397 / 405 */
23
+ export declare function parseCpmmPool(account: AccountInfo): CpmmState | null;
24
+ /** 恒定乘积的兑换(与程序 CurveCalculator::swap_base_input 一致),返回给用户的输出(未扣转账手续费) */
25
+ export declare function cpmmSwapBaseInput(amountIn: bigint, reserveIn: bigint, reserveOut: bigint, tradeFeeRate: bigint, creatorFeeRate: bigint, creatorFeeOnInput: boolean): bigint;
26
+ export declare function cpmmPool(state: CpmmState): SwapPool;
27
+ export {};
28
+ //# sourceMappingURL=cpmm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpmm.d.ts","sourceRoot":"","sources":["../../src/swap/cpmm.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAIlE,OAAO,EAAgJ,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAKzL,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,+KAA+K;AAC/K,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAkBpE;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,OAAO,GACzB,MAAM,CAUR;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,CA6DnD"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Raydium CPMM 的兑换:swap_base_input。报价照搬程序(raydium-cp-swap curve/calculator.rs):
3
+ * 交易费(含创建者手续费,从输入或输出扣)向上取整,恒定乘积向下取整,储备 = 金库余额 − 协议 / 基金 / 创建者手续费;输入输出的 Token-2022 转账手续费都算
4
+ */
5
+ import { parseTokenAccount } from '../layout.js';
6
+ import { RAYDIUM_CPMM_AUTHORITY, RAYDIUM_CPMM_PROGRAM_ID } from '../lp.js';
7
+ import { Writer, anchorIx, r, w } from '../liquidity/common.js';
8
+ import { Bytes, UnsupportedPool, mulDivCeil, mulDivFloor, need, swapMint, transferFee } from './common.js';
9
+ const FEE_DENOMINATOR = 1000000n;
10
+ const POOL_SIZE = 637;
11
+ /** PoolState:amm_config 8、vault 72 / 104、mint 168 / 200、observation 296、status 329、协议 / 基金手续费 341…、open_time 373、creator_fee_on 389、enable_creator_fee 390、创建者手续费 397 / 405 */
12
+ export function parseCpmmPool(account) {
13
+ if (account.owner !== RAYDIUM_CPMM_PROGRAM_ID || account.data.length !== POOL_SIZE)
14
+ return null;
15
+ const b = new Bytes(account.data);
16
+ return {
17
+ address: account.address,
18
+ config: b.key(8),
19
+ vault0: b.key(72),
20
+ vault1: b.key(104),
21
+ mint0: b.key(168),
22
+ mint1: b.key(200),
23
+ observation: b.key(296),
24
+ status: b.u8(329),
25
+ openTime: b.u64(373),
26
+ reserved0: b.u64(341) + b.u64(357) + b.u64(397),
27
+ reserved1: b.u64(349) + b.u64(365) + b.u64(405),
28
+ creatorFeeOn: b.u8(389),
29
+ creatorFeeEnabled: b.u8(390) !== 0,
30
+ };
31
+ }
32
+ /** 恒定乘积的兑换(与程序 CurveCalculator::swap_base_input 一致),返回给用户的输出(未扣转账手续费) */
33
+ export function cpmmSwapBaseInput(amountIn, reserveIn, reserveOut, tradeFeeRate, creatorFeeRate, creatorFeeOnInput) {
34
+ let afterFee;
35
+ if (creatorFeeOnInput) {
36
+ afterFee = amountIn - mulDivCeil(amountIn, tradeFeeRate + creatorFeeRate, FEE_DENOMINATOR);
37
+ }
38
+ else {
39
+ afterFee = amountIn - mulDivCeil(amountIn, tradeFeeRate, FEE_DENOMINATOR);
40
+ }
41
+ if (afterFee < 0n)
42
+ return 0n;
43
+ const swapped = mulDivFloor(afterFee, reserveOut, reserveIn + afterFee);
44
+ return creatorFeeOnInput ? swapped : swapped - mulDivCeil(swapped, creatorFeeRate, FEE_DENOMINATOR);
45
+ }
46
+ export function cpmmPool(state) {
47
+ const mints = (get) => [
48
+ swapMint(state.mint0, need(get, state.mint0, 'Token mint')),
49
+ swapMint(state.mint1, need(get, state.mint1, 'Token mint')),
50
+ ];
51
+ return {
52
+ protocol: 'raydium-cpmm',
53
+ address: state.address,
54
+ mint0: state.mint0,
55
+ mint1: state.mint1,
56
+ mints,
57
+ accounts: () => [state.config, state.vault0, state.vault1, state.mint0, state.mint1],
58
+ quote(get, amountIn, zeroForOne, env) {
59
+ // status 第 2 位(Swap)为 1 表示禁止兑换
60
+ if (state.status & 4)
61
+ throw new UnsupportedPool('Swap is disabled on this pool');
62
+ if (env.timestamp < state.openTime)
63
+ throw new UnsupportedPool('Pool is not open yet');
64
+ const [m0, m1] = mints(get);
65
+ const config = need(get, state.config, 'AMM config').data;
66
+ if (config.length < 124)
67
+ throw new UnsupportedPool('Unexpected AMM config');
68
+ const c = new Bytes(config);
69
+ // AmmConfig:trade_fee_rate 12、creator_fee_rate 108
70
+ const tradeFeeRate = c.u64(12);
71
+ const creatorFeeRate = state.creatorFeeEnabled ? c.u64(108) : 0n;
72
+ const v0 = parseTokenAccount(need(get, state.vault0, 'Pool vault').data).amount;
73
+ const v1 = parseTokenAccount(need(get, state.vault1, 'Pool vault').data).amount;
74
+ if (v0 < state.reserved0 || v1 < state.reserved1)
75
+ throw new UnsupportedPool('Pool vault is below the owed fees');
76
+ const [reserveIn, reserveOut] = zeroForOne ? [v0 - state.reserved0, v1 - state.reserved1] : [v1 - state.reserved1, v0 - state.reserved0];
77
+ const [mintIn, mintOut] = zeroForOne ? [m0, m1] : [m1, m0];
78
+ // 创建者手续费:0 两边都从输入扣;1 只收 token0;2 只收 token1(收哪种代币,卖出它时从输入扣,买入它时从输出扣)
79
+ const creatorOnInput = state.creatorFeeOn === 0 || (state.creatorFeeOn === 1 && zeroForOne) || (state.creatorFeeOn === 2 && !zeroForOne);
80
+ const actualIn = amountIn - transferFee(mintIn, amountIn, env.epoch);
81
+ if (actualIn <= 0n)
82
+ return { amountIn, amountOut: 0n, accounts: [] };
83
+ const out = cpmmSwapBaseInput(actualIn, reserveIn, reserveOut, tradeFeeRate, creatorFeeRate, creatorOnInput);
84
+ const received = out - transferFee(mintOut, out, env.epoch);
85
+ return { amountIn, amountOut: received > 0n ? received : 0n, accounts: [] };
86
+ },
87
+ instruction(get, owner, input, output, zeroForOne, quote, minOut) {
88
+ const [m0, m1] = mints(get);
89
+ const [mintIn, mintOut] = zeroForOne ? [m0, m1] : [m1, m0];
90
+ const [vaultIn, vaultOut] = zeroForOne ? [state.vault0, state.vault1] : [state.vault1, state.vault0];
91
+ return {
92
+ programId: RAYDIUM_CPMM_PROGRAM_ID,
93
+ keys: [
94
+ r(owner, true),
95
+ r(RAYDIUM_CPMM_AUTHORITY),
96
+ r(state.config),
97
+ w(state.address),
98
+ w(input),
99
+ w(output),
100
+ w(vaultIn),
101
+ w(vaultOut),
102
+ r(mintIn.program),
103
+ r(mintOut.program),
104
+ r(mintIn.mint),
105
+ r(mintOut.mint),
106
+ w(state.observation),
107
+ ],
108
+ data: new Writer().bytes(anchorIx('swap_base_input')).u64(quote.amountIn).u64(minOut).build(),
109
+ };
110
+ },
111
+ };
112
+ }
113
+ //# sourceMappingURL=cpmm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpmm.js","sourceRoot":"","sources":["../../src/swap/cpmm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import type { SolanaClient } from '../client.js';
2
+ import { type AccountInfo } from '../layout.js';
3
+ import { type SolanaLpToken } from '../lp.js';
4
+ import type { SendOptions, WriteResult, WriteStatus } from '../write/send.js';
5
+ import { type SignerInput } from '../write/signer.js';
6
+ import { type Instruction } from '../write/transaction.js';
7
+ import { type SolanaSwapProtocol, type SwapPool } from './common.js';
8
+ export type { SolanaSwapProtocol } from './common.js';
9
+ /** 两跳默认的中间代币:Wrapped SOL、USDC、USDT */
10
+ export declare const SWAP_INTERMEDIATES: readonly string[];
11
+ /** 默认的协议:能按两个 mint 推导池子地址的三个,加上 pools 里给出的 AMM v4 池子 */
12
+ export declare const SWAP_PROTOCOLS: readonly SolanaSwapProtocol[];
13
+ type Amount = bigint | number | string;
14
+ export interface SolanaSwapParams {
15
+ /** 卖出 / 买入的代币 mint;原生 SOL 用 NATIVE_MINT(So111…112)或客户端的 nativeMints,池子里按 Wrapped SOL */
16
+ tokenIn: string;
17
+ tokenOut: string;
18
+ /** 卖出的数量:amountIn(最小单位)和 amountInFormatted(按精度换算,如 '1.5')二选一 */
19
+ amountIn?: Amount;
20
+ amountInFormatted?: string;
21
+ }
22
+ export interface SolanaSwapOptions {
23
+ /** 价格滑点(比例,0.005 = 0.5%),最少收到 = 报价 × (1 − slippage),默认 0.005 */
24
+ slippage?: number;
25
+ /**
26
+ * Wrapped SOL 用 SOL 支付 / 收取(自动包装 / 解包),默认 true。
27
+ * 用的是 wSOL 的关联代币账户:原来没有时创建、用完关闭(换回 SOL);原来就有时只补差额、不关闭(买入的 SOL 留在 wSOL 账户里)
28
+ */
29
+ native?: boolean;
30
+ /** 只用这些协议,默认 SWAP_PROTOCOLS(全部四个) */
31
+ protocols?: readonly SolanaSwapProtocol[];
32
+ /** 两跳的中间代币,默认 SWAP_INTERMEDIATES(Wrapped SOL、USDC、USDT);传 [] 只找直接兑换 */
33
+ intermediates?: readonly string[];
34
+ /**
35
+ * 额外的池子地址(四个协议都可以,按账户所属程序识别)。Raydium AMM v4 的池子地址不能从两个 mint 推导,要用的话在这里给出;
36
+ * 用 seed_index 建的 Raydium CLMM 池子、非默认配置的 Orca 池子同样
37
+ */
38
+ pools?: readonly string[];
39
+ /** 按两个 mint 推导池子地址(Raydium CLMM / CPMM 的每个 AmmConfig、Orca 的每个费率档位),默认 true;false 时只用 pools 里的 */
40
+ discover?: boolean;
41
+ signal?: AbortSignal;
42
+ }
43
+ export interface SolanaSwapHop {
44
+ protocol: SolanaSwapProtocol;
45
+ protocolName: string;
46
+ pool: string;
47
+ tokenIn: string;
48
+ tokenOut: string;
49
+ /** 这一跳卖出的数量和预计收到的数量(已扣转账手续费) */
50
+ amountIn: string;
51
+ amountOut: string;
52
+ /** 这一跳的最少收到(按滑点),交易里的 other_amount_threshold */
53
+ amountOutMin: string;
54
+ }
55
+ export interface SolanaSwapRoute {
56
+ /** 经过的代币(池子里的 mint,SOL 是 Wrapped SOL) */
57
+ path: string[];
58
+ hops: SolanaSwapHop[];
59
+ /** 预计收到的数量(最小单位) */
60
+ amountOut: string;
61
+ /**
62
+ * 用于比较路线的数量:两跳时第二跳按第一跳的报价全部卖出能拿到的(实际第二跳只卖第一跳的最少收到,多出的中间代币留在账户里,见 leftover);
63
+ * 直接兑换等于 amountOut
64
+ */
65
+ value: string;
66
+ }
67
+ export interface SolanaSwapStep {
68
+ /** setup:创建代币账户(能和兑换放进同一笔交易时会合并);swap:包装 SOL、兑换、解包 */
69
+ kind: 'setup' | 'swap';
70
+ instructions: Instruction[];
71
+ }
72
+ /** 兑换的计划:报价 + 按顺序执行的指令。只读取、不签名,可以当作报价 */
73
+ export interface SolanaSwapPlan {
74
+ owner: string;
75
+ tokenIn: SolanaLpToken;
76
+ tokenOut: SolanaLpToken;
77
+ amountIn: string;
78
+ amountInFormatted: string | null;
79
+ /** 预计收到的数量(按当前链上状态本地计算,与程序的取整一致)和最少收到的数量(按滑点) */
80
+ amountOut: string;
81
+ amountOutFormatted: string | null;
82
+ amountOutMin: string;
83
+ amountOutMinFormatted: string | null;
84
+ /** 1 个 tokenIn 换多少 tokenOut(按这笔的数量,路线的 value) */
85
+ price: number | null;
86
+ /** 价格影响(0~1):这笔的价格比极小数量(1 / 10000)的价格差多少;算不出时为 null */
87
+ priceImpact: number | null;
88
+ route: SolanaSwapRoute;
89
+ /** 所有候选路线,按 value 从高到低(含选中的) */
90
+ routes: SolanaSwapRoute[];
91
+ /** 两跳时留在账户里的中间代币(第一跳报价 − 第一跳最少收到,按当前状态);中间代币是 Wrapped SOL 且原来没有 wSOL 账户时随账户关闭换回 SOL */
92
+ leftover: {
93
+ mint: string;
94
+ amount: string;
95
+ } | null;
96
+ /** 哪一边用 SOL(自动包装 / 解包) */
97
+ native: 'tokenIn' | 'tokenOut' | null;
98
+ /** 没有用上的池子和原因(不支持的代币扩展、需要位图扩展、流动性不足等) */
99
+ skipped: Array<{
100
+ protocol: SolanaSwapProtocol;
101
+ pool: string;
102
+ reason: string;
103
+ }>;
104
+ steps: SolanaSwapStep[];
105
+ }
106
+ /** 按账户所属程序解析池子(包内使用,测试也用) */
107
+ export declare function parseSwapPool(account: AccountInfo): SwapPool | null;
108
+ /**
109
+ * 报价并构建兑换的指令(不签名):选输出最多的路线,最少收到 = 报价 × (1 − slippage)。
110
+ *
111
+ * ```ts
112
+ * const plan = await buildSwap(client, owner, { tokenIn: NATIVE_MINT, tokenOut: USDC, amountInFormatted: '0.5' })
113
+ * plan.amountOutFormatted // '93.41'
114
+ * plan.route.hops // [{ protocol: 'raydium-clmm', pool: '3ucNos4N…', … }]
115
+ * ```
116
+ */
117
+ export declare function buildSwap(client: SolanaClient, owner: string, params: SolanaSwapParams, options?: SolanaSwapOptions): Promise<SolanaSwapPlan>;
118
+ export interface SolanaSwapSendOptions extends SolanaSwapOptions, Omit<SendOptions, 'onUpdate' | 'signal'> {
119
+ /** 发送前检查卖出的余额够不够,默认 true */
120
+ checkBalance?: boolean;
121
+ onUpdate?: (result: SolanaSwapStepResult) => void;
122
+ }
123
+ export interface SolanaSwapStepResult extends WriteResult {
124
+ kind: SolanaSwapStep['kind'];
125
+ }
126
+ export interface SolanaSwapResult {
127
+ plan: SolanaSwapPlan;
128
+ /** 与 plan.steps 一一对应 */
129
+ results: SolanaSwapStepResult[];
130
+ /** 兑换那一步的状态和签名 */
131
+ status: WriteStatus;
132
+ signature: string | null;
133
+ }
134
+ /**
135
+ * 兑换:构建(同 buildSwap)后用 from 签名发送(钱包同 /write 的 batchCall)。创建代币账户和兑换能放进同一笔交易时合并成一笔
136
+ *
137
+ * ```ts
138
+ * const r = await swap(client, secretKey, { tokenIn: USDC, tokenOut: NATIVE_MINT, amountInFormatted: '100' }, { slippage: 0.01 })
139
+ * r.status // 'confirmed'
140
+ * ```
141
+ */
142
+ export declare function swap(client: SolanaClient, from: SignerInput, params: SolanaSwapParams, options?: SolanaSwapSendOptions): Promise<SolanaSwapResult>;
143
+ /** 卖出 SOL 时给手续费、wSOL 和收到代币的 ATA 租金留的 lamports(约 0.01 SOL) */
144
+ export declare const SWAP_SOL_RESERVE = 10000000n;
145
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/swap/index.ts"],"names":[],"mappings":"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"}