@w3lib/evm-batch-call 0.5.0 → 0.7.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 +38 -0
- package/README.md +240 -4
- package/contracts/TokenProbe.sol +103 -0
- package/dist/aggregate.d.ts.map +1 -1
- package/dist/aggregate.js +114 -3
- package/dist/aggregate.js.map +1 -1
- package/dist/approvals.d.ts +169 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +310 -0
- package/dist/approvals.js.map +1 -0
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +4 -0
- package/dist/chains.js.map +1 -1
- package/dist/fees.d.ts +97 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/fees.js +115 -0
- package/dist/fees.js.map +1 -0
- package/dist/http.d.ts +10 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +30 -0
- package/dist/http.js.map +1 -0
- package/dist/liquidity/common.d.ts +72 -0
- package/dist/liquidity/common.d.ts.map +1 -0
- package/dist/liquidity/common.js +271 -0
- package/dist/liquidity/common.js.map +1 -0
- package/dist/liquidity/concentrated.d.ts +19 -0
- package/dist/liquidity/concentrated.d.ts.map +1 -0
- package/dist/liquidity/concentrated.js +106 -0
- package/dist/liquidity/concentrated.js.map +1 -0
- package/dist/liquidity/index.d.ts +42 -0
- package/dist/liquidity/index.d.ts.map +1 -0
- package/dist/liquidity/index.js +143 -0
- package/dist/liquidity/index.js.map +1 -0
- package/dist/liquidity/types.d.ts +182 -0
- package/dist/liquidity/types.d.ts.map +1 -0
- package/dist/liquidity/types.js +2 -0
- package/dist/liquidity/types.js.map +1 -0
- package/dist/liquidity/v2.d.ts +5 -0
- package/dist/liquidity/v2.d.ts.map +1 -0
- package/dist/liquidity/v2.js +342 -0
- package/dist/liquidity/v2.js.map +1 -0
- package/dist/liquidity/v3.d.ts +6 -0
- package/dist/liquidity/v3.d.ts.map +1 -0
- package/dist/liquidity/v3.js +310 -0
- package/dist/liquidity/v3.js.map +1 -0
- package/dist/liquidity/v4.d.ts +5 -0
- package/dist/liquidity/v4.d.ts.map +1 -0
- package/dist/liquidity/v4.js +279 -0
- package/dist/liquidity/v4.js.map +1 -0
- package/dist/lp.d.ts +10 -2
- package/dist/lp.d.ts.map +1 -1
- package/dist/lp.js +31 -19
- package/dist/lp.js.map +1 -1
- package/dist/lpMath.d.ts +55 -0
- package/dist/lpMath.d.ts.map +1 -1
- package/dist/lpMath.js +209 -0
- package/dist/lpMath.js.map +1 -1
- package/dist/multicall.d.ts.map +1 -1
- package/dist/multicall.js +3 -0
- package/dist/multicall.js.map +1 -1
- package/dist/names.d.ts +55 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +93 -0
- package/dist/names.js.map +1 -0
- package/dist/owner.d.ts +4 -26
- package/dist/owner.d.ts.map +1 -1
- package/dist/owner.js +7 -112
- package/dist/owner.js.map +1 -1
- package/dist/portfolio.d.ts +54 -0
- package/dist/portfolio.d.ts.map +1 -0
- package/dist/portfolio.js +49 -0
- package/dist/portfolio.js.map +1 -0
- package/dist/price.d.ts +95 -0
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +329 -0
- package/dist/price.js.map +1 -0
- package/dist/risk.d.ts +42 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +134 -0
- package/dist/risk.js.map +1 -0
- package/dist/rpcNodes.d.ts.map +1 -1
- package/dist/rpcNodes.js +18 -0
- package/dist/rpcNodes.js.map +1 -1
- package/dist/subpaths/approvals.d.ts +26 -0
- package/dist/subpaths/approvals.d.ts.map +1 -0
- package/dist/subpaths/approvals.js +27 -0
- package/dist/subpaths/approvals.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/liquidity.d.ts +24 -0
- package/dist/subpaths/liquidity.d.ts.map +1 -0
- package/dist/subpaths/liquidity.js +21 -0
- package/dist/subpaths/liquidity.js.map +1 -0
- package/dist/subpaths/lp.d.ts +1 -1
- package/dist/subpaths/lp.d.ts.map +1 -1
- package/dist/subpaths/lp.js +1 -1
- package/dist/subpaths/lp.js.map +1 -1
- package/dist/subpaths/names.d.ts +35 -0
- package/dist/subpaths/names.d.ts.map +1 -0
- package/dist/subpaths/names.js +39 -0
- package/dist/subpaths/names.js.map +1 -0
- package/dist/subpaths/price.d.ts +38 -0
- package/dist/subpaths/price.d.ts.map +1 -0
- package/dist/subpaths/price.js +40 -0
- package/dist/subpaths/price.js.map +1 -0
- package/dist/subpaths/risk.d.ts +19 -0
- package/dist/subpaths/risk.d.ts.map +1 -0
- package/dist/subpaths/risk.js +20 -0
- package/dist/subpaths/risk.js.map +1 -0
- package/dist/subpaths/swap.d.ts +19 -0
- package/dist/subpaths/swap.d.ts.map +1 -0
- package/dist/subpaths/swap.js +20 -0
- package/dist/subpaths/swap.js.map +1 -0
- package/dist/swap.d.ts +128 -0
- package/dist/swap.d.ts.map +1 -0
- package/dist/swap.js +291 -0
- package/dist/swap.js.map +1 -0
- package/dist/tokenProbe.d.ts +3 -0
- package/dist/tokenProbe.d.ts.map +1 -0
- package/dist/tokenProbe.js +4 -0
- package/dist/tokenProbe.js.map +1 -0
- package/dist/write/tron.d.ts +27 -0
- package/dist/write/tron.d.ts.map +1 -1
- package/dist/write/tron.js +30 -0
- package/dist/write/tron.js.map +1 -1
- package/package.json +32 -1
- package/src/aggregate.ts +110 -3
- package/src/approvals.ts +462 -0
- package/src/chains.ts +4 -0
- package/src/fees.ts +201 -0
- package/src/http.ts +34 -0
- package/src/liquidity/common.ts +314 -0
- package/src/liquidity/concentrated.ts +121 -0
- package/src/liquidity/index.ts +171 -0
- package/src/liquidity/types.ts +194 -0
- package/src/liquidity/v2.ts +371 -0
- package/src/liquidity/v3.ts +382 -0
- package/src/liquidity/v4.ts +348 -0
- package/src/lp.ts +39 -19
- package/src/lpMath.ts +223 -0
- package/src/multicall.ts +3 -0
- package/src/names.ts +141 -0
- package/src/owner.ts +7 -138
- package/src/portfolio.ts +91 -0
- package/src/price.ts +415 -0
- package/src/risk.ts +166 -0
- package/src/rpcNodes.ts +18 -0
- package/src/subpaths/approvals.ts +48 -0
- package/src/subpaths/fees.ts +43 -0
- package/src/subpaths/liquidity.ts +52 -0
- package/src/subpaths/lp.ts +20 -1
- package/src/subpaths/names.ts +43 -0
- package/src/subpaths/price.ts +60 -0
- package/src/subpaths/risk.ts +23 -0
- package/src/subpaths/swap.ts +36 -0
- package/src/swap.ts +413 -0
- package/src/tokenProbe.ts +5 -0
- package/src/write/tron.ts +48 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { Interface } from 'ethers'
|
|
2
|
+
|
|
3
|
+
import type { Provider } from '../provider.js'
|
|
4
|
+
import { batchCall, tronModule } from '../write/batch.js'
|
|
5
|
+
import { WriteRpc } from '../write/rpc.js'
|
|
6
|
+
import { resolveSigner, type SignerInput } from '../write/signer.js'
|
|
7
|
+
import { ZERO_ADDRESS, createCtx, evm, positionVersion, protocolById } from './common.js'
|
|
8
|
+
import type {
|
|
9
|
+
AddLiquidityParams,
|
|
10
|
+
CollectFeesParams,
|
|
11
|
+
LiquidityOptions,
|
|
12
|
+
LiquidityPlan,
|
|
13
|
+
LiquidityResult,
|
|
14
|
+
LiquiditySendOptions,
|
|
15
|
+
LiquidityTx,
|
|
16
|
+
LiquidityTxResult,
|
|
17
|
+
RemoveLiquidityParams,
|
|
18
|
+
} from './types.js'
|
|
19
|
+
import { v2Add, v2Remove } from './v2.js'
|
|
20
|
+
import { v3Add, v3Remove } from './v3.js'
|
|
21
|
+
import { v4Add, v4Remove } from './v4.js'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 添加流动性的计划(不签名、不发送):新建仓位,或往已有仓位追加。返回预计的数量和要按顺序发送的交易(授权在前)。
|
|
25
|
+
* 只做读取,也可以当作报价:输入一边的数量,看另一边要多少、能拿到多少流动性
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* // 新建 V3 仓位:价格区间按 tokenB / tokenA,给一边的数量
|
|
29
|
+
* const plan = await buildAddLiquidity(multi, owner, { protocol: 'pancakeswap-v3', tokenA: WBNB, tokenB: USDT, fee: 500, priceLower: 550, priceUpper: 650, amountAFormatted: '1' })
|
|
30
|
+
* plan.amount1Formatted // 需要的 USDT
|
|
31
|
+
* plan.transactions // [approve…, add],可以交给钱包逐笔发送
|
|
32
|
+
* // 往已有仓位追加(position 可以直接用 getLpPositions 的结果)
|
|
33
|
+
* await buildAddLiquidity(multi, owner, { position, amount0Formatted: '0.5' })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export async function buildAddLiquidity(provider: Provider, owner: string, params: AddLiquidityParams, options: LiquidityOptions = {}): Promise<LiquidityPlan> {
|
|
37
|
+
const ctx = await createCtx(provider, owner, options)
|
|
38
|
+
if ('position' in params) {
|
|
39
|
+
const version = positionVersion(ctx, params.position)
|
|
40
|
+
return version === 'v2' ? v2Add(ctx, params) : version === 'v3' ? v3Add(ctx, params) : v4Add(ctx, params)
|
|
41
|
+
}
|
|
42
|
+
const protocol = protocolById(ctx, params.protocol)
|
|
43
|
+
const resolved = { ...params, protocol }
|
|
44
|
+
return protocol.version === 'v2' ? v2Add(ctx, resolved) : protocol.version === 'v3' ? v3Add(ctx, resolved) : v4Add(ctx, resolved)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 移除流动性的计划(不签名、不发送):按比例或指定数量移除,V3 / V4 同时领取全部未领取的手续费。
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* await buildRemoveLiquidity(multi, owner, { position, percent: 50 })
|
|
52
|
+
* await buildRemoveLiquidity(multi, owner, { position, burn: true }) // 全部移除并销毁 NFT
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export async function buildRemoveLiquidity(provider: Provider, owner: string, params: RemoveLiquidityParams, options: LiquidityOptions = {}): Promise<LiquidityPlan> {
|
|
56
|
+
const ctx = await createCtx(provider, owner, options)
|
|
57
|
+
const version = positionVersion(ctx, params.position)
|
|
58
|
+
return version === 'v2' ? v2Remove(ctx, params) : version === 'v3' ? v3Remove(ctx, params) : v4Remove(ctx, params)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 只领取 V3 / V4 仓位的手续费(不动流动性)的计划 */
|
|
62
|
+
export async function buildCollectFees(provider: Provider, owner: string, params: CollectFeesParams, options: LiquidityOptions = {}): Promise<LiquidityPlan> {
|
|
63
|
+
const ctx = await createCtx(provider, owner, options)
|
|
64
|
+
const version = positionVersion(ctx, params.position)
|
|
65
|
+
if (version === 'v2') {
|
|
66
|
+
throw new Error('V2 has no separate fees: they are part of the LP tokens, remove liquidity to get them')
|
|
67
|
+
}
|
|
68
|
+
return version === 'v3' ? v3Remove(ctx, { position: params.position }, true) : v4Remove(ctx, { position: params.position }, true)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 添加流动性:构建计划(同 buildAddLiquidity)后用 from 签名发送,授权不够时先发授权交易。
|
|
73
|
+
* from 与 /write 的 batchCall 相同:私钥、ethers Signer、浏览器钱包(Tron 上也可以是 tronWeb / adapter)
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* const { status, tokenId, plan } = await addLiquidity(multi, privateKey, { protocol: 'uniswap-v3', tokenA: NATIVE_TOKEN, tokenB: USDC, fee: 500, fullRange: true, amountAFormatted: '0.1' })
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export async function addLiquidity(provider: Provider, from: SignerInput, params: AddLiquidityParams, options: LiquiditySendOptions = {}): Promise<LiquidityResult> {
|
|
80
|
+
const plan = await buildAddLiquidity(provider, await signerAddress(provider, from), params, options)
|
|
81
|
+
if (options.checkBalance ?? true) {
|
|
82
|
+
await checkBalance(provider, plan)
|
|
83
|
+
}
|
|
84
|
+
return execute(provider, from, plan, options)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** 移除流动性:构建计划(同 buildRemoveLiquidity)后用 from 签名发送 */
|
|
88
|
+
export async function removeLiquidity(provider: Provider, from: SignerInput, params: RemoveLiquidityParams, options: LiquiditySendOptions = {}): Promise<LiquidityResult> {
|
|
89
|
+
const plan = await buildRemoveLiquidity(provider, await signerAddress(provider, from), params, options)
|
|
90
|
+
return execute(provider, from, plan, options)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** 领取 V3 / V4 仓位的手续费 */
|
|
94
|
+
export async function collectFees(provider: Provider, from: SignerInput, params: CollectFeesParams, options: LiquiditySendOptions = {}): Promise<LiquidityResult> {
|
|
95
|
+
const plan = await buildCollectFees(provider, await signerAddress(provider, from), params, options)
|
|
96
|
+
return execute(provider, from, plan, options)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 签名器的地址(Tron 上为 T 地址),不发交易 */
|
|
100
|
+
async function signerAddress(provider: Provider, from: SignerInput): Promise<string> {
|
|
101
|
+
const tron = await tronModule(provider)
|
|
102
|
+
return tron ? tron.tronSignerAddress(from) : (await resolveSigner(from)).address
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** 添加前检查余额:代币按预计数量,主币按附带的 value(不含手续费) */
|
|
106
|
+
async function checkBalance(provider: Provider, plan: LiquidityPlan): Promise<void> {
|
|
107
|
+
const needs: Array<[string, bigint]> = []
|
|
108
|
+
// V4 追加时先自动领取手续费、与存入相抵:只需要差额
|
|
109
|
+
const offset = (amount: string, fees: string) => {
|
|
110
|
+
const need = BigInt(amount) - (plan.version === 'v4' && plan.tokenId !== null ? BigInt(fees) : 0n)
|
|
111
|
+
return need > 0n ? need : 0n
|
|
112
|
+
}
|
|
113
|
+
if (plan.native !== 'token0') needs.push([plan.token0.address, offset(plan.amount0, plan.fees0)])
|
|
114
|
+
if (plan.native !== 'token1') needs.push([plan.token1.address, offset(plan.amount1, plan.fees1)])
|
|
115
|
+
if (BigInt(plan.value) > 0n) needs.push([provider.nativeTokens[0] ?? ZERO_ADDRESS, BigInt(plan.value)])
|
|
116
|
+
const list = needs.filter(([, amount]) => amount > 0n)
|
|
117
|
+
if (!list.length) {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
const balances = await provider.balances(plan.owner, list.map(([token]) => token))
|
|
121
|
+
list.forEach(([token, amount], i) => {
|
|
122
|
+
const b = balances[i]
|
|
123
|
+
// 读不到余额的不拦(预估 gas 时也会失败)
|
|
124
|
+
if (b?.success && BigInt(b.balance) < amount) {
|
|
125
|
+
throw new Error(`Insufficient balance of ${token}: need ${amount}, have ${b.balance}`)
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const transferTopic = new Interface(['event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)']).getEvent('Transfer')?.topicHash as string
|
|
131
|
+
|
|
132
|
+
async function execute(provider: Provider, from: SignerInput, plan: LiquidityPlan, options: LiquiditySendOptions): Promise<LiquidityResult> {
|
|
133
|
+
const { transactions } = plan
|
|
134
|
+
const results = (
|
|
135
|
+
await batchCall(
|
|
136
|
+
provider,
|
|
137
|
+
transactions.map((tx) => ({ from, to: tx.to, data: tx.data, value: BigInt(tx.value) })),
|
|
138
|
+
{
|
|
139
|
+
...options,
|
|
140
|
+
mode: 'tx',
|
|
141
|
+
// 授权失败时不发主交易
|
|
142
|
+
continueOnError: false,
|
|
143
|
+
onUpdate: options.onUpdate ? (r) => options.onUpdate?.({ ...r, kind: (transactions[r.index] as LiquidityTx).kind }) : undefined,
|
|
144
|
+
},
|
|
145
|
+
)
|
|
146
|
+
).map((r, i): LiquidityTxResult => ({ ...r, kind: (transactions[i] as LiquidityTx).kind }))
|
|
147
|
+
const main = results[results.length - 1] as LiquidityTxResult
|
|
148
|
+
let tokenId: string | null = plan.tokenId
|
|
149
|
+
if (plan.action === 'add' && plan.tokenId === null && plan.version !== 'v2') {
|
|
150
|
+
tokenId = main.status === 'confirmed' && main.hash ? await mintedTokenId(provider, plan, main.hash) : null
|
|
151
|
+
}
|
|
152
|
+
return { plan, results, status: main.status, hash: main.hash, tokenId }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 新建仓位的 tokenId:主交易回执里仓位合约从零地址转出的 NFT(Tron 上不读,为 null) */
|
|
156
|
+
async function mintedTokenId(provider: Provider, plan: LiquidityPlan, hash: string): Promise<string | null> {
|
|
157
|
+
try {
|
|
158
|
+
if (await tronModule(provider)) {
|
|
159
|
+
return null
|
|
160
|
+
}
|
|
161
|
+
const receipt = await (await WriteRpc.from(provider)).receipt(hash)
|
|
162
|
+
const pm = evm((plan.transactions[plan.transactions.length - 1] as { to: string }).to)
|
|
163
|
+
const log = receipt?.logs.find(
|
|
164
|
+
(l) => l.topics.length === 4 && l.topics[0] === transferTopic && BigInt(l.topics[1] as string) === 0n && evm(l.address) === pm,
|
|
165
|
+
)
|
|
166
|
+
return log ? BigInt(log.topics[3] as string).toString() : null
|
|
167
|
+
} catch {
|
|
168
|
+
return null // 读回执失败不影响结果(交易已确认)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { BigNumberish } from 'ethers'
|
|
2
|
+
|
|
3
|
+
import type { LpPosition, LpProtocol, LpToken, LpVersion } from '../lp.js'
|
|
4
|
+
import type { SendOptions, TronSendOptions, WriteResult, WriteStatus } from '../write/send.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 已有的仓位:直接传 getLpPositions 查到的 LpPosition,或者只传能定位仓位的字段。
|
|
8
|
+
* - V2:pool(LP 代币地址)
|
|
9
|
+
* - V3 / V4:tokenId,加上 positionManager 或 protocol(协议 id / LpProtocol)
|
|
10
|
+
*/
|
|
11
|
+
export interface PositionRef {
|
|
12
|
+
pool?: string
|
|
13
|
+
tokenId?: string | number | bigint
|
|
14
|
+
positionManager?: string
|
|
15
|
+
protocol?: string | LpProtocol
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** 往已有仓位追加流动性:两边数量给一边即可(另一边按当前价格算),也可以都给(按较少的一边) */
|
|
19
|
+
export interface IncreaseLiquidityParams {
|
|
20
|
+
position: PositionRef | LpPosition
|
|
21
|
+
/** token0 的数量:amount0(最小单位)和 amount0Formatted(按精度换算,如 '1.5')二选一 */
|
|
22
|
+
amount0?: BigNumberish
|
|
23
|
+
amount0Formatted?: string
|
|
24
|
+
amount1?: BigNumberish
|
|
25
|
+
amount1Formatted?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 新建仓位(V3 / V4:一个新的仓位 NFT;V2:往 tokenA / tokenB 的池子里加,池子不存在时创建)。
|
|
30
|
+
* 两个代币不分顺序,价格都是“1 个 tokenA 值多少个 tokenB”
|
|
31
|
+
*/
|
|
32
|
+
export interface NewPositionParams {
|
|
33
|
+
/** 协议 id(如 'uniswap-v3')或自己的 LpProtocol */
|
|
34
|
+
protocol: string | LpProtocol
|
|
35
|
+
/** 代币地址;主币用 NATIVE_TOKEN 或零地址(V2 / V3 换成包装币、用主币支付;V4 是主币池子) */
|
|
36
|
+
tokenA: string
|
|
37
|
+
tokenB: string
|
|
38
|
+
/** V3 / V4:手续费档位(百万分之一:500 = 0.05%) */
|
|
39
|
+
fee?: number
|
|
40
|
+
/** V4:tick 间距,默认按手续费档位(100 → 1、500 → 10、3000 → 60、10000 → 200) */
|
|
41
|
+
tickSpacing?: number
|
|
42
|
+
/** V4:池子的 hooks 合约,默认零地址 */
|
|
43
|
+
hooks?: string
|
|
44
|
+
/** V3 / V4:价格区间(tokenB / tokenA,取最近的可用 tick);或直接给 tickLower / tickUpper;或 fullRange */
|
|
45
|
+
priceLower?: string | number
|
|
46
|
+
priceUpper?: string | number
|
|
47
|
+
/** 池子里的 tick(token1 / token0 方向),必须是 tickSpacing 的整数倍 */
|
|
48
|
+
tickLower?: number
|
|
49
|
+
tickUpper?: number
|
|
50
|
+
/** 全区间(最小到最大的可用 tick) */
|
|
51
|
+
fullRange?: boolean
|
|
52
|
+
/** tokenA / tokenB 的数量:amount(最小单位)和 formatted 二选一;两边给一边即可,V2 新池子两边都要给 */
|
|
53
|
+
amountA?: BigNumberish
|
|
54
|
+
amountAFormatted?: string
|
|
55
|
+
amountB?: BigNumberish
|
|
56
|
+
amountBFormatted?: string
|
|
57
|
+
/** 池子不存在(或还没初始化)时用这个价格创建(tokenB / tokenA)。不传时池子不存在会报错 */
|
|
58
|
+
initialPrice?: string | number
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type AddLiquidityParams = IncreaseLiquidityParams | NewPositionParams
|
|
62
|
+
|
|
63
|
+
export interface RemoveLiquidityParams {
|
|
64
|
+
position: PositionRef | LpPosition
|
|
65
|
+
/** 移除的比例(百分数,(0, 100]),默认 100 */
|
|
66
|
+
percent?: number
|
|
67
|
+
/** 或者直接给移除的流动性:V3 / V4 是 L,V2 是 LP 代币数量(最小单位) */
|
|
68
|
+
liquidity?: BigNumberish
|
|
69
|
+
/** V3 / V4:全部移除后销毁仓位 NFT,默认 false */
|
|
70
|
+
burn?: boolean
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface CollectFeesParams {
|
|
74
|
+
/** V3 / V4 的仓位(V2 的手续费已经计入 LP 份额,没有单独领取) */
|
|
75
|
+
position: PositionRef | LpPosition
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface LiquidityOptions {
|
|
79
|
+
/** 价格滑点(比例,0.005 = 0.5%),默认 0.005 */
|
|
80
|
+
slippage?: number
|
|
81
|
+
/** 交易的有效期(秒),默认 1200 */
|
|
82
|
+
deadline?: number
|
|
83
|
+
/** 收到 LP 代币 / 仓位 NFT / 移除的代币的地址,默认 owner */
|
|
84
|
+
recipient?: string
|
|
85
|
+
/**
|
|
86
|
+
* V2 / V3:包装币(WETH / WBNB …)那一边用主币支付 / 收取。
|
|
87
|
+
* 新建仓位时 tokenA / tokenB 传主币地址会自动开启;往已有仓位追加、移除、领取时默认 false(收到包装币)。V4 的主币池子不需要
|
|
88
|
+
*/
|
|
89
|
+
native?: boolean
|
|
90
|
+
/** 授权额度:'exact'(默认,本次需要的数量)或 'max'(无限额度,之后不用再授权) */
|
|
91
|
+
approve?: 'exact' | 'max'
|
|
92
|
+
/** 内置表里没有的协议(自己的 LpProtocol),定位仓位时也会用到 */
|
|
93
|
+
protocols?: readonly LpProtocol[]
|
|
94
|
+
/** V4:传给 hooks 的 hookData,默认 '0x' */
|
|
95
|
+
hookData?: string
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** 一笔要发送的交易 */
|
|
99
|
+
export interface LiquidityTx {
|
|
100
|
+
/**
|
|
101
|
+
* - approve:代币授权给 Router / 仓位合约 / Permit2
|
|
102
|
+
* - permit2:Permit2 授权给 V4 的仓位合约
|
|
103
|
+
* - add / remove / collect:添加 / 移除流动性、领取手续费
|
|
104
|
+
*/
|
|
105
|
+
kind: 'approve' | 'permit2' | 'add' | 'remove' | 'collect'
|
|
106
|
+
to: string
|
|
107
|
+
data: string
|
|
108
|
+
/** 附带的主币(最小单位) */
|
|
109
|
+
value: string
|
|
110
|
+
/** approve / permit2:授权的代币、被授权方、额度 */
|
|
111
|
+
token?: string
|
|
112
|
+
spender?: string
|
|
113
|
+
amount?: string
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 添加 / 移除流动性的计划:预计的数量 + 要按顺序发送的交易(授权在前)。
|
|
118
|
+
* 只做读取、不签名,可以当作报价用(输入一边数量,看另一边要多少)
|
|
119
|
+
*/
|
|
120
|
+
export interface LiquidityPlan {
|
|
121
|
+
action: 'add' | 'remove' | 'collect'
|
|
122
|
+
chainId: number
|
|
123
|
+
version: LpVersion
|
|
124
|
+
/** 协议 id / 显示名 */
|
|
125
|
+
protocol: string
|
|
126
|
+
protocolName: string
|
|
127
|
+
/** 池子地址(V4 为 poolId);V2 / V3 的池子还不存在时为 null */
|
|
128
|
+
pool: string | null
|
|
129
|
+
/** 这次会创建(初始化)池子 */
|
|
130
|
+
createPool: boolean
|
|
131
|
+
owner: string
|
|
132
|
+
recipient: string
|
|
133
|
+
token0: LpToken
|
|
134
|
+
token1: LpToken
|
|
135
|
+
/** 已有仓位的 tokenId;新建 V3 / V4 仓位、V2 为 null */
|
|
136
|
+
tokenId: string | null
|
|
137
|
+
/** V3 / V4:仓位的 tick 区间、池子当前的 tick 和价格(token1 / token0,按精度换算,只用于展示) */
|
|
138
|
+
tickLower: number | null
|
|
139
|
+
tickUpper: number | null
|
|
140
|
+
tick: number | null
|
|
141
|
+
price: number | null
|
|
142
|
+
priceLower: number | null
|
|
143
|
+
priceUpper: number | null
|
|
144
|
+
/** 添加 / 移除的流动性:V3 / V4 是 L;V2 是 LP 代币数量(添加时为预计) */
|
|
145
|
+
liquidity: string
|
|
146
|
+
/** 按当前价格预计存入 / 取出的数量(不含手续费) */
|
|
147
|
+
amount0: string
|
|
148
|
+
amount1: string
|
|
149
|
+
amount0Formatted: string | null
|
|
150
|
+
amount1Formatted: string | null
|
|
151
|
+
/** 添加:最多会用掉的数量(V4 按滑点上浮;V2 / V3 即传给合约的数量);移除:为 null */
|
|
152
|
+
amount0Max: string | null
|
|
153
|
+
amount1Max: string | null
|
|
154
|
+
/** 移除:至少会拿到的数量(价格在滑点范围外时交易失败);添加:为 null */
|
|
155
|
+
amount0Min: string | null
|
|
156
|
+
amount1Min: string | null
|
|
157
|
+
/**
|
|
158
|
+
* 一并领取的未领取手续费(V3 移除 / 领取;V4 修改流动性时自动领取)。V2 没有单独的手续费,为 '0'
|
|
159
|
+
*/
|
|
160
|
+
fees0: string
|
|
161
|
+
fees1: string
|
|
162
|
+
fees0Formatted: string | null
|
|
163
|
+
fees1Formatted: string | null
|
|
164
|
+
/** 哪一边用主币支付 / 收取(V2 / V3 的包装币那一边开启 native 时;V4 主币池子的 token0);都不是时为 null */
|
|
165
|
+
native: 'token0' | 'token1' | null
|
|
166
|
+
/** 主交易附带的主币 */
|
|
167
|
+
value: string
|
|
168
|
+
/** 交易的截止时间(秒级时间戳) */
|
|
169
|
+
deadline: number
|
|
170
|
+
/** 按顺序发送;不需要授权时只有一笔 */
|
|
171
|
+
transactions: LiquidityTx[]
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface LiquiditySendOptions extends LiquidityOptions, Omit<SendOptions, 'onUpdate'>, TronSendOptions {
|
|
175
|
+
/** 发送前检查余额够不够(添加时),默认 true */
|
|
176
|
+
checkBalance?: boolean
|
|
177
|
+
/** 每笔交易状态变化时回调(index 是在 plan.transactions 里的下标) */
|
|
178
|
+
onUpdate?: (result: LiquidityTxResult) => void
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface LiquidityTxResult extends WriteResult {
|
|
182
|
+
kind: LiquidityTx['kind']
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface LiquidityResult {
|
|
186
|
+
plan: LiquidityPlan
|
|
187
|
+
/** 与 plan.transactions 一一对应 */
|
|
188
|
+
results: LiquidityTxResult[]
|
|
189
|
+
/** 主交易(最后一笔)的状态和哈希 */
|
|
190
|
+
status: WriteStatus
|
|
191
|
+
hash: string | null
|
|
192
|
+
/** 新建的 V3 / V4 仓位的 tokenId(EVM 上主交易 confirmed 后从回执里读;其他情况为 null) */
|
|
193
|
+
tokenId: string | null
|
|
194
|
+
}
|