@w3lib/solana-batch-call 0.4.0 → 0.6.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.
- package/CHANGELOG.md +45 -0
- package/README.md +343 -3
- package/dist/approvals.d.ts +129 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +221 -0
- package/dist/approvals.js.map +1 -0
- package/dist/batchPlan.d.ts +52 -0
- package/dist/batchPlan.d.ts.map +1 -0
- package/dist/batchPlan.js +85 -0
- package/dist/batchPlan.js.map +1 -0
- package/dist/claim.d.ts +161 -0
- package/dist/claim.d.ts.map +1 -0
- package/dist/claim.js +197 -0
- package/dist/claim.js.map +1 -0
- package/dist/decode.d.ts +22 -0
- package/dist/decode.d.ts.map +1 -0
- package/dist/decode.js +187 -0
- package/dist/decode.js.map +1 -0
- package/dist/describe.d.ts +26 -0
- package/dist/describe.d.ts.map +1 -0
- package/dist/describe.js +58 -0
- package/dist/describe.js.map +1 -0
- package/dist/fees.d.ts +89 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/fees.js +166 -0
- package/dist/fees.js.map +1 -0
- package/dist/history.d.ts +125 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +231 -0
- package/dist/history.js.map +1 -0
- package/dist/historyHelius.d.ts +52 -0
- package/dist/historyHelius.d.ts.map +1 -0
- package/dist/historyHelius.js +125 -0
- package/dist/historyHelius.js.map +1 -0
- package/dist/layout.d.ts +2 -0
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +2 -2
- package/dist/layout.js.map +1 -1
- package/dist/liquidity/orca.d.ts +6 -0
- package/dist/liquidity/orca.d.ts.map +1 -1
- package/dist/liquidity/orca.js +14 -3
- package/dist/liquidity/orca.js.map +1 -1
- package/dist/liquidity/raydiumClmm.d.ts +6 -0
- package/dist/liquidity/raydiumClmm.d.ts.map +1 -1
- package/dist/liquidity/raydiumClmm.js +12 -5
- package/dist/liquidity/raydiumClmm.js.map +1 -1
- package/dist/lp.d.ts +55 -15
- package/dist/lp.d.ts.map +1 -1
- package/dist/lp.js +98 -46
- package/dist/lp.js.map +1 -1
- package/dist/lpMath.d.ts +22 -0
- package/dist/lpMath.d.ts.map +1 -1
- package/dist/lpMath.js +21 -0
- package/dist/lpMath.js.map +1 -1
- package/dist/names.d.ts +68 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +257 -0
- package/dist/names.js.map +1 -0
- package/dist/pools.d.ts +9 -0
- package/dist/pools.d.ts.map +1 -0
- package/dist/pools.js +45 -0
- package/dist/pools.js.map +1 -0
- package/dist/portfolio.d.ts +64 -0
- package/dist/portfolio.d.ts.map +1 -0
- package/dist/portfolio.js +57 -0
- package/dist/portfolio.js.map +1 -0
- package/dist/price.d.ts +90 -0
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +287 -0
- package/dist/price.js.map +1 -0
- package/dist/programs.d.ts +19 -0
- package/dist/programs.d.ts.map +1 -0
- package/dist/programs.js +175 -0
- package/dist/programs.js.map +1 -0
- package/dist/reclaim.d.ts +190 -0
- package/dist/reclaim.d.ts.map +1 -0
- package/dist/reclaim.js +399 -0
- package/dist/reclaim.js.map +1 -0
- package/dist/risk.d.ts +84 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +211 -0
- package/dist/risk.js.map +1 -0
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +36 -10
- package/dist/rpc.js.map +1 -1
- package/dist/simulate.d.ts +106 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +418 -0
- package/dist/simulate.js.map +1 -0
- package/dist/subpaths/approvals.d.ts +29 -0
- package/dist/subpaths/approvals.d.ts.map +1 -0
- package/dist/subpaths/approvals.js +30 -0
- package/dist/subpaths/approvals.js.map +1 -0
- package/dist/subpaths/claim.d.ts +31 -0
- package/dist/subpaths/claim.d.ts.map +1 -0
- package/dist/subpaths/claim.js +31 -0
- package/dist/subpaths/claim.js.map +1 -0
- package/dist/subpaths/fees.d.ts +23 -0
- package/dist/subpaths/fees.d.ts.map +1 -0
- package/dist/subpaths/fees.js +25 -0
- package/dist/subpaths/fees.js.map +1 -0
- package/dist/subpaths/history.d.ts +21 -0
- package/dist/subpaths/history.d.ts.map +1 -0
- package/dist/subpaths/history.js +22 -0
- package/dist/subpaths/history.js.map +1 -0
- package/dist/subpaths/lp.d.ts +2 -2
- package/dist/subpaths/lp.d.ts.map +1 -1
- package/dist/subpaths/lp.js +2 -2
- package/dist/subpaths/lp.js.map +1 -1
- package/dist/subpaths/names.d.ts +37 -0
- package/dist/subpaths/names.d.ts.map +1 -0
- package/dist/subpaths/names.js +27 -0
- package/dist/subpaths/names.js.map +1 -0
- package/dist/subpaths/price.d.ts +40 -0
- package/dist/subpaths/price.d.ts.map +1 -0
- package/dist/subpaths/price.js +43 -0
- package/dist/subpaths/price.js.map +1 -0
- package/dist/subpaths/reclaim.d.ts +34 -0
- package/dist/subpaths/reclaim.d.ts.map +1 -0
- package/dist/subpaths/reclaim.js +34 -0
- package/dist/subpaths/reclaim.js.map +1 -0
- package/dist/subpaths/risk.d.ts +28 -0
- package/dist/subpaths/risk.d.ts.map +1 -0
- package/dist/subpaths/risk.js +30 -0
- package/dist/subpaths/risk.js.map +1 -0
- package/dist/subpaths/simulate.d.ts +22 -0
- package/dist/subpaths/simulate.d.ts.map +1 -0
- package/dist/subpaths/simulate.js +23 -0
- package/dist/subpaths/simulate.js.map +1 -0
- package/dist/subpaths/swap.d.ts +22 -0
- package/dist/subpaths/swap.d.ts.map +1 -0
- package/dist/subpaths/swap.js +21 -0
- package/dist/subpaths/swap.js.map +1 -0
- package/dist/subpaths/write.d.ts +1 -1
- package/dist/subpaths/write.d.ts.map +1 -1
- package/dist/subpaths/write.js +1 -1
- package/dist/subpaths/write.js.map +1 -1
- package/dist/swap/amm.d.ts +20 -0
- package/dist/swap/amm.d.ts.map +1 -0
- package/dist/swap/amm.js +77 -0
- package/dist/swap/amm.js.map +1 -0
- package/dist/swap/clmmMath.d.ts +24 -0
- package/dist/swap/clmmMath.d.ts.map +1 -0
- package/dist/swap/clmmMath.js +82 -0
- package/dist/swap/clmmMath.js.map +1 -0
- package/dist/swap/common.d.ts +68 -0
- package/dist/swap/common.d.ts.map +1 -0
- package/dist/swap/common.js +65 -0
- package/dist/swap/common.js.map +1 -0
- package/dist/swap/cpmm.d.ts +28 -0
- package/dist/swap/cpmm.d.ts.map +1 -0
- package/dist/swap/cpmm.js +113 -0
- package/dist/swap/cpmm.js.map +1 -0
- package/dist/swap/index.d.ts +145 -0
- package/dist/swap/index.d.ts.map +1 -0
- package/dist/swap/index.js +349 -0
- package/dist/swap/index.js.map +1 -0
- package/dist/swap/orca.d.ts +50 -0
- package/dist/swap/orca.d.ts.map +1 -0
- package/dist/swap/orca.js +382 -0
- package/dist/swap/orca.js.map +1 -0
- package/dist/swap/raydiumClmm.d.ts +62 -0
- package/dist/swap/raydiumClmm.d.ts.map +1 -0
- package/dist/swap/raydiumClmm.js +447 -0
- package/dist/swap/raydiumClmm.js.map +1 -0
- package/dist/tradeCheck.d.ts +45 -0
- package/dist/tradeCheck.d.ts.map +1 -0
- package/dist/tradeCheck.js +131 -0
- package/dist/tradeCheck.js.map +1 -0
- package/dist/write/instructions.d.ts +9 -0
- package/dist/write/instructions.d.ts.map +1 -1
- package/dist/write/instructions.js +40 -1
- package/dist/write/instructions.js.map +1 -1
- package/dist/write/transaction.d.ts +23 -0
- package/dist/write/transaction.d.ts.map +1 -1
- package/dist/write/transaction.js +50 -0
- package/dist/write/transaction.js.map +1 -1
- package/package.json +66 -14
- package/src/approvals.ts +358 -0
- package/src/batchPlan.ts +137 -0
- package/src/claim.ts +323 -0
- package/src/decode.ts +202 -0
- package/src/describe.ts +77 -0
- package/src/fees.ts +259 -0
- package/src/history.ts +336 -0
- package/src/historyHelius.ts +136 -0
- package/src/layout.ts +2 -2
- package/src/liquidity/orca.ts +15 -5
- package/src/liquidity/raydiumClmm.ts +13 -5
- package/src/lp.ts +148 -59
- package/src/lpMath.ts +38 -0
- package/src/names.ts +329 -0
- package/src/pools.ts +43 -0
- package/src/portfolio.ts +124 -0
- package/src/price.ts +366 -0
- package/src/programs.ts +216 -0
- package/src/reclaim.ts +547 -0
- package/src/risk.ts +243 -0
- package/src/rpc.ts +39 -10
- package/src/simulate.ts +535 -0
- package/src/subpaths/approvals.ts +47 -0
- package/src/subpaths/claim.ts +53 -0
- package/src/subpaths/fees.ts +41 -0
- package/src/subpaths/history.ts +38 -0
- package/src/subpaths/lp.ts +5 -1
- package/src/subpaths/names.ts +45 -0
- package/src/subpaths/price.ts +62 -0
- package/src/subpaths/reclaim.ts +57 -0
- package/src/subpaths/risk.ts +36 -0
- package/src/subpaths/simulate.ts +37 -0
- package/src/subpaths/swap.ts +41 -0
- package/src/subpaths/write.ts +2 -0
- package/src/swap/amm.ts +88 -0
- package/src/swap/clmmMath.ts +96 -0
- package/src/swap/common.ts +113 -0
- package/src/swap/cpmm.ts +132 -0
- package/src/swap/index.ts +467 -0
- package/src/swap/orca.ts +397 -0
- package/src/swap/raydiumClmm.ts +464 -0
- package/src/tradeCheck.ts +166 -0
- package/src/write/instructions.ts +43 -1
- package/src/write/transaction.ts +62 -0
package/dist/subpaths/write.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
export { batchCall, type BatchCallMode, type BatchCallOptions, type WriteCall } from '../write/batch.js';
|
|
16
16
|
export { batchCollect, type BatchCollectOptions, type CollectItemResult, type CollectResult } from '../write/collect.js';
|
|
17
17
|
export { batchTransfer, type BatchTransferOptions, type TransferItem, type TransferMode, type TransferResult } from '../write/transfer.js';
|
|
18
|
-
export { COMPUTE_BUDGET_PROGRAM_ID, closeAccount, createAssociatedTokenAccountIdempotent, setComputeUnitLimit, setComputeUnitPrice, systemTransfer, transferChecked, } from '../write/instructions.js';
|
|
18
|
+
export { COMPUTE_BUDGET_PROGRAM_ID, closeAccount, createAssociatedTokenAccountIdempotent, harvestWithheldTokensToMint, revoke, setComputeUnitLimit, setComputeUnitPrice, systemTransfer, transferChecked, } from '../write/instructions.js';
|
|
19
19
|
export type { SendOptions, WriteResult, WriteStatus } from '../write/send.js';
|
|
20
20
|
export type { SignerInput, WriteSigner } from '../write/signer.js';
|
|
21
21
|
export type { AccountMeta, Instruction, InstructionInput } from '../write/transaction.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/subpaths/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACxG,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxH,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1I,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,sCAAsC,EACtC,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC7E,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAClE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/subpaths/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACxG,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxH,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1I,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,sCAAsC,EACtC,2BAA2B,EAC3B,MAAM,EACN,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC7E,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAClE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/subpaths/write.js
CHANGED
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
export { batchCall } from '../write/batch.js';
|
|
16
16
|
export { batchCollect } from '../write/collect.js';
|
|
17
17
|
export { batchTransfer } from '../write/transfer.js';
|
|
18
|
-
export { COMPUTE_BUDGET_PROGRAM_ID, closeAccount, createAssociatedTokenAccountIdempotent, setComputeUnitLimit, setComputeUnitPrice, systemTransfer, transferChecked, } from '../write/instructions.js';
|
|
18
|
+
export { COMPUTE_BUDGET_PROGRAM_ID, closeAccount, createAssociatedTokenAccountIdempotent, harvestWithheldTokensToMint, revoke, setComputeUnitLimit, setComputeUnitPrice, systemTransfer, transferChecked, } from '../write/instructions.js';
|
|
19
19
|
//# sourceMappingURL=write.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/subpaths/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,SAAS,EAA6D,MAAM,mBAAmB,CAAA;AACxG,OAAO,EAAE,YAAY,EAAwE,MAAM,qBAAqB,CAAA;AACxH,OAAO,EAAE,aAAa,EAAwF,MAAM,sBAAsB,CAAA;AAC1I,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,sCAAsC,EACtC,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA"}
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/subpaths/write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,SAAS,EAA6D,MAAM,mBAAmB,CAAA;AACxG,OAAO,EAAE,YAAY,EAAwE,MAAM,qBAAqB,CAAA;AACxH,OAAO,EAAE,aAAa,EAAwF,MAAM,sBAAsB,CAAA;AAC1I,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,sCAAsC,EACtC,2BAA2B,EAC3B,MAAM,EACN,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type AccountInfo } from '../layout.js';
|
|
2
|
+
import { type SwapPool } from './common.js';
|
|
3
|
+
interface AmmState {
|
|
4
|
+
address: string;
|
|
5
|
+
status: bigint;
|
|
6
|
+
swapFeeNumerator: bigint;
|
|
7
|
+
swapFeeDenominator: bigint;
|
|
8
|
+
needTakePnl0: bigint;
|
|
9
|
+
needTakePnl1: bigint;
|
|
10
|
+
openTime: bigint;
|
|
11
|
+
vault0: string;
|
|
12
|
+
vault1: string;
|
|
13
|
+
mint0: string;
|
|
14
|
+
mint1: string;
|
|
15
|
+
}
|
|
16
|
+
/** AmmInfo(无判别符):status 0、fees.swap_fee 176 / 184、need_take_pnl_coin 192、need_take_pnl_pc 200、pool_open_time 224、vault 336 / 368、mint 400 / 432 */
|
|
17
|
+
export declare function parseAmmV4Pool(account: AccountInfo): AmmState | null;
|
|
18
|
+
export declare function ammV4Pool(state: AmmState): SwapPool;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=amm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amm.d.ts","sourceRoot":"","sources":["../../src/swap/amm.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAIlE,OAAO,EAAqH,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAS9J,UAAU,QAAQ;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;IACxB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,mJAAmJ;AACnJ,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAgBpE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAoCnD"}
|
package/dist/swap/amm.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raydium AMM v4 的兑换:swap_base_in_v2(指令 16,不需要 OpenBook 账户)。报价照搬程序(raydium-amm processor.rs):
|
|
3
|
+
* 手续费 = ceil(输入 × swap_fee_numerator / swap_fee_denominator),储备 = 金库余额 − need_take_pnl,恒定乘积向下取整。只支持 SPL Token
|
|
4
|
+
*/
|
|
5
|
+
import { TOKEN_PROGRAM_ID } from '../constants.js';
|
|
6
|
+
import { parseTokenAccount } from '../layout.js';
|
|
7
|
+
import { RAYDIUM_AMM_AUTHORITY, RAYDIUM_AMM_PROGRAM_ID } from '../lp.js';
|
|
8
|
+
import { Writer, r, w } from '../liquidity/common.js';
|
|
9
|
+
import { Bytes, UnsupportedPool, mulDivCeil, mulDivFloor, need, swapMint } from './common.js';
|
|
10
|
+
const POOL_SIZE = 752;
|
|
11
|
+
/**
|
|
12
|
+
* 只支持 SwapOnly(6,不再用 OpenBook 挂单,现在的池子基本都是):swap_base_in_v2 不带 OpenBook 账户,
|
|
13
|
+
* 还连着 OpenBook 的池子(Initialized 1、WaitingTrade 7)没有对照程序源码验证过能不能用,不报价,免得排第一后在链上失败
|
|
14
|
+
*/
|
|
15
|
+
const SWAP_STATUSES = new Set([6n]);
|
|
16
|
+
/** AmmInfo(无判别符):status 0、fees.swap_fee 176 / 184、need_take_pnl_coin 192、need_take_pnl_pc 200、pool_open_time 224、vault 336 / 368、mint 400 / 432 */
|
|
17
|
+
export function parseAmmV4Pool(account) {
|
|
18
|
+
if (account.owner !== RAYDIUM_AMM_PROGRAM_ID || account.data.length !== POOL_SIZE)
|
|
19
|
+
return null;
|
|
20
|
+
const b = new Bytes(account.data);
|
|
21
|
+
return {
|
|
22
|
+
address: account.address,
|
|
23
|
+
status: b.u64(0),
|
|
24
|
+
swapFeeNumerator: b.u64(176),
|
|
25
|
+
swapFeeDenominator: b.u64(184),
|
|
26
|
+
needTakePnl0: b.u64(192),
|
|
27
|
+
needTakePnl1: b.u64(200),
|
|
28
|
+
openTime: b.u64(224),
|
|
29
|
+
vault0: b.key(336),
|
|
30
|
+
vault1: b.key(368),
|
|
31
|
+
mint0: b.key(400),
|
|
32
|
+
mint1: b.key(432),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function ammV4Pool(state) {
|
|
36
|
+
const mints = (get) => [
|
|
37
|
+
swapMint(state.mint0, need(get, state.mint0, 'Token mint')),
|
|
38
|
+
swapMint(state.mint1, need(get, state.mint1, 'Token mint')),
|
|
39
|
+
];
|
|
40
|
+
return {
|
|
41
|
+
protocol: 'raydium-amm',
|
|
42
|
+
address: state.address,
|
|
43
|
+
mint0: state.mint0,
|
|
44
|
+
mint1: state.mint1,
|
|
45
|
+
mints,
|
|
46
|
+
accounts: () => [state.vault0, state.vault1, state.mint0, state.mint1],
|
|
47
|
+
quote(get, amountIn, zeroForOne, env) {
|
|
48
|
+
if (!SWAP_STATUSES.has(state.status))
|
|
49
|
+
throw new UnsupportedPool(`Swap is not allowed in pool status ${state.status}`);
|
|
50
|
+
if (env.timestamp < state.openTime)
|
|
51
|
+
throw new UnsupportedPool('Pool is not open yet');
|
|
52
|
+
if (state.swapFeeDenominator === 0n)
|
|
53
|
+
throw new UnsupportedPool('Invalid pool fees');
|
|
54
|
+
const [m0, m1] = mints(get);
|
|
55
|
+
if (m0.program !== TOKEN_PROGRAM_ID || m1.program !== TOKEN_PROGRAM_ID)
|
|
56
|
+
throw new UnsupportedPool('AMM v4 supports only SPL Token mints');
|
|
57
|
+
const v0 = parseTokenAccount(need(get, state.vault0, 'Pool vault').data).amount;
|
|
58
|
+
const v1 = parseTokenAccount(need(get, state.vault1, 'Pool vault').data).amount;
|
|
59
|
+
if (v0 < state.needTakePnl0 || v1 < state.needTakePnl1)
|
|
60
|
+
throw new UnsupportedPool('Pool vault is below the pending PnL');
|
|
61
|
+
const [reserveIn, reserveOut] = zeroForOne ? [v0 - state.needTakePnl0, v1 - state.needTakePnl1] : [v1 - state.needTakePnl1, v0 - state.needTakePnl0];
|
|
62
|
+
const fee = mulDivCeil(amountIn, state.swapFeeNumerator, state.swapFeeDenominator);
|
|
63
|
+
const afterFee = amountIn - fee;
|
|
64
|
+
const out = afterFee > 0n ? mulDivFloor(reserveOut, afterFee, reserveIn + afterFee) : 0n;
|
|
65
|
+
// 程序要求输出小于储备
|
|
66
|
+
return { amountIn, amountOut: out < reserveOut ? out : 0n, accounts: [] };
|
|
67
|
+
},
|
|
68
|
+
instruction(_get, owner, input, output, _zeroForOne, quote, minOut) {
|
|
69
|
+
return {
|
|
70
|
+
programId: RAYDIUM_AMM_PROGRAM_ID,
|
|
71
|
+
keys: [r(TOKEN_PROGRAM_ID), w(state.address), r(RAYDIUM_AMM_AUTHORITY), w(state.vault0), w(state.vault1), w(input), w(output), r(owner, true)],
|
|
72
|
+
data: new Writer().u8(16).u64(quote.amountIn).u64(minOut).build(),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=amm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amm.js","sourceRoot":"","sources":["../../src/swap/amm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const FEE_RATE_DENOMINATOR = 1000000n;
|
|
2
|
+
export declare class SwapMathError extends Error {
|
|
3
|
+
}
|
|
4
|
+
/** 价格从 a 到 b(任意顺序)对应的 token0 数量:L · 2^64 · (hi − lo) / (lo · hi) */
|
|
5
|
+
export declare function amount0Delta(a: bigint, b: bigint, liquidity: bigint, roundUp: boolean): bigint;
|
|
6
|
+
/** 价格从 a 到 b 对应的 token1 数量:L · (hi − lo) / 2^64 */
|
|
7
|
+
export declare function amount1Delta(a: bigint, b: bigint, liquidity: bigint, roundUp: boolean): bigint;
|
|
8
|
+
/** 卖出 amount 后的 sqrt 价格(向不越过目标价格的方向取整):卖 token0 时价格下降,卖 token1 时上升 */
|
|
9
|
+
export declare function nextSqrtPriceFromInput(sqrtPrice: bigint, liquidity: bigint, amount: bigint, zeroForOne: boolean): bigint;
|
|
10
|
+
export interface SwapStep {
|
|
11
|
+
/** 走到的 sqrt 价格 */
|
|
12
|
+
sqrtPrice: bigint;
|
|
13
|
+
/** 计入价格变动的输入(不含手续费) */
|
|
14
|
+
amountIn: bigint;
|
|
15
|
+
/** 给用户的输出(手续费从输出扣时已扣除) */
|
|
16
|
+
amountOut: bigint;
|
|
17
|
+
feeAmount: bigint;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 一步兑换:从当前价格向目标价格,最多用 remaining 个输入。
|
|
21
|
+
* feeOnInput(Orca 和 Raydium 的默认):输入先按费率扣手续费;否则(Raydium fee_on):输出按费率扣
|
|
22
|
+
*/
|
|
23
|
+
export declare function computeSwapStep(sqrtCurrent: bigint, sqrtTarget: bigint, liquidity: bigint, remaining: bigint, feeRate: bigint, zeroForOne: boolean, feeOnInput: boolean, program: 'raydium' | 'orca'): SwapStep;
|
|
24
|
+
//# sourceMappingURL=clmmMath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clmmMath.d.ts","sourceRoot":"","sources":["../../src/swap/clmmMath.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,oBAAoB,WAAa,CAAA;AAE9C,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAE3C,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAM9F;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAI9F;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CASxH;AAED,MAAM,WAAW,QAAQ;IACvB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,OAAO,EACnB,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,SAAS,GAAG,MAAM,GAC1B,QAAQ,CAiCV"}
|
|
@@ -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":"AAAA;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,GAAG,GAAG,EAAE,IAAI,GAAG,CAAA;AACrB,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAU,CAAA;AAE9C,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG;AAE3C,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS,EAAE,SAAiB,EAAE,OAAgB;IACpF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,GAAG,CAAA;IAC1C,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,CAAA;IACnB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAA;AACrD,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS,EAAE,SAAiB,EAAE,OAAgB;IACpF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,MAAM,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;IAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAA;AACnD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,SAAiB,EAAE,MAAc,EAAE,UAAmB;IAC9G,IAAI,SAAS,KAAK,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAA;IAC/D,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,SAAS,IAAI,GAAG,CAAA;QAC5B,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;QACpC,OAAO,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;IACxC,CAAC;IACD,OAAO,SAAS,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAA;AAChD,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,UAAkB,EAClB,SAAiB,EACjB,SAAiB,EACjB,OAAe,EACf,UAAmB,EACnB,UAAmB,EACnB,OAA2B;IAE3B,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,oBAAoB,GAAG,OAAO,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAA;IACrH,6CAA6C;IAC7C,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;IAC/I,IAAI,QAAgB,CAAA;IACpB,IAAI,QAAgB,CAAA;IACpB,IAAI,SAAiB,CAAA;IACrB,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;IAC1J,IAAI,OAAO,GAAG,UAAU,IAAI,OAAO,IAAI,cAAc,IAAI,UAAU,CAAA;IACnE,iDAAiD;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACxC,IAAI,OAAO,IAAI,OAAO,KAAK,SAAS,IAAI,GAAG,GAAG,OAAO;QAAE,OAAO,GAAG,KAAK,CAAA;IACtE,IAAI,OAAO,EAAE,CAAC;QACZ,QAAQ,GAAG,UAAU,CAAA;QACrB,QAAQ,GAAG,UAAU,CAAA;QACrB,SAAS,GAAG,GAAG,CAAA;IACjB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,sBAAsB,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,CAAC,CAAA;QACrF,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;QACnI,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;IACxI,CAAC;IACD,IAAI,QAAQ,GAAG,OAAO,IAAI,SAAS,GAAG,OAAO;QAAE,MAAM,IAAI,aAAa,CAAC,0BAA0B,CAAC,CAAA;IAClG,IAAI,UAAU,CAAC,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,GAAG,UAAU;QAAE,MAAM,IAAI,aAAa,CAAC,6BAA6B,CAAC,CAAA;IACtH,IAAI,SAAiB,CAAA;IACrB,IAAI,UAAU,EAAE,CAAC;QACf,SAAS,GAAG,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,CAAA;IAC5H,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAA;QAChE,SAAS,IAAI,SAAS,CAAA;QACtB,+BAA+B;QAC/B,IAAI,QAAQ,KAAK,UAAU;YAAE,QAAQ,GAAG,SAAS,CAAA;IACnD,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;AAChE,CAAC"}
|
|
@@ -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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"}
|