liquid-sdk 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_README.md +22 -1
- package/dist/index.d.mts +23 -8
- package/dist/index.d.ts +23 -8
- package/dist/index.js +56 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/skills/bid-in-auction.md +129 -90
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liquid-sdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "TypeScript SDK to deploy ERC-20 tokens with Uniswap V4 liquidity on Base — zero API keys, one dependency (viem)",
|
|
5
5
|
"author": "Liquid Protocol",
|
|
6
6
|
"homepage": "https://github.com/craigbots/liquid-sdk#readme",
|
package/skills/bid-in-auction.md
CHANGED
|
@@ -8,8 +8,8 @@ When a new token is deployed on Liquid Protocol, a **sniper auction** activates
|
|
|
8
8
|
|
|
9
9
|
1. **Fee decay**: The auction starts with an **80% fee** on swaps and decays linearly to **40% over 32 seconds**
|
|
10
10
|
2. **Gas price bidding**: Bidders compete by setting their transaction gas price **above the pool's gas peg**. The difference between your gas price and the gas peg determines your bid amount
|
|
11
|
-
3. **Rounds**: The auction runs in discrete rounds
|
|
12
|
-
4. **Winner takes the swap**: The highest gas-price transaction in
|
|
11
|
+
3. **Rounds**: The auction runs in discrete rounds every 2 blocks (5 rounds max). Each round is valid for exactly **one block** (`nextAuctionBlock`)
|
|
12
|
+
4. **Winner takes the swap**: The highest gas-price transaction in the auction block wins the right to swap at the current fee rate
|
|
13
13
|
5. **Revenue distribution**: Auction revenue (bid amounts) flows to the protocol and LP holders
|
|
14
14
|
|
|
15
15
|
The auction is **not** a separate step from trading — it's a modified swap where your gas price encodes your bid.
|
|
@@ -21,7 +21,7 @@ npm install liquid-sdk viem
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
You need:
|
|
24
|
-
- A **private key** with ETH on Base
|
|
24
|
+
- A **private key** with ETH on Base (enough for gas + bid + swap amount)
|
|
25
25
|
- The **token address** or **pool ID** of a recently launched token
|
|
26
26
|
- An **RPC endpoint** for Base mainnet
|
|
27
27
|
|
|
@@ -31,7 +31,7 @@ You need:
|
|
|
31
31
|
import { createPublicClient, createWalletClient, http, parseEther } from "viem";
|
|
32
32
|
import { base } from "viem/chains";
|
|
33
33
|
import { privateKeyToAccount } from "viem/accounts";
|
|
34
|
-
import { LiquidSDK } from "liquid-sdk";
|
|
34
|
+
import { LiquidSDK, EXTERNAL } from "liquid-sdk";
|
|
35
35
|
|
|
36
36
|
const account = privateKeyToAccount(PRIVATE_KEY);
|
|
37
37
|
const publicClient = createPublicClient({ chain: base, transport: http(RPC_URL) });
|
|
@@ -39,6 +39,31 @@ const walletClient = createWalletClient({ account, chain: base, transport: http(
|
|
|
39
39
|
const sdk = new LiquidSDK({ publicClient, walletClient });
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
## Critical Concepts
|
|
43
|
+
|
|
44
|
+
Before bidding, understand these mechanics:
|
|
45
|
+
|
|
46
|
+
### Two Separate ETH Costs
|
|
47
|
+
- **`bidAmount`** (msg.value): ETH sent to the auction as your bid. Goes to protocol/LP.
|
|
48
|
+
- **`amountIn`** (WETH transfer): The actual swap input. Pulled from your WETH balance via `transferFrom`. **This is separate from the bid.**
|
|
49
|
+
|
|
50
|
+
The SDK **automatically wraps ETH → WETH and approves the SniperUtilV2** if your WETH balance or allowance is insufficient. You just need enough total ETH.
|
|
51
|
+
|
|
52
|
+
### Gas Price = Bid Encoding
|
|
53
|
+
The bid amount is encoded in the transaction's gas price: `bidAmount = (tx.gasprice - gasPeg) × paymentPerGasUnit`. Both `maxFeePerGas` **and** `maxPriorityFeePerGas` must be set to the calculated value, otherwise Base's EIP-1559 will compute a lower effective gas price.
|
|
54
|
+
|
|
55
|
+
### Gas Estimation Must Be Skipped
|
|
56
|
+
`eth_estimateGas` simulates at `baseFee` (~5M wei on Base), which is below the `gasPeg` (~6.3M wei). This causes the auction check to fail during estimation. The SDK sets `gas: 800_000n` manually.
|
|
57
|
+
|
|
58
|
+
### Block Timing is Critical
|
|
59
|
+
The auction is valid at **exactly** `nextAuctionBlock` — not before, not after. Submit your transaction ~1 block early (when `currentBlock === nextAuctionBlock - 1`) to land in the target block. Base has ~2s block time.
|
|
60
|
+
|
|
61
|
+
### zeroForOne Depends on Token Sort Order
|
|
62
|
+
Do **not** hardcode `zeroForOne: true`. Determine it from the pool key:
|
|
63
|
+
```typescript
|
|
64
|
+
const zeroForOne = poolKey.currency0.toLowerCase() === EXTERNAL.WETH.toLowerCase();
|
|
65
|
+
```
|
|
66
|
+
|
|
42
67
|
## Step-by-Step: Bidding in an Auction
|
|
43
68
|
|
|
44
69
|
### Step 1: Get the Auction State
|
|
@@ -60,47 +85,27 @@ console.log("Current fee:", auction.currentFee); // in uniBps (800000 = 80%)
|
|
|
60
85
|
**Key fields:**
|
|
61
86
|
| Field | Type | Description |
|
|
62
87
|
|-------|------|-------------|
|
|
63
|
-
| `nextAuctionBlock` | `bigint` |
|
|
88
|
+
| `nextAuctionBlock` | `bigint` | The ONE block where bids are valid |
|
|
64
89
|
| `round` | `bigint` | Current round number (must match when bidding) |
|
|
65
90
|
| `gasPeg` | `bigint` | Base gas price reference — you bid by exceeding this |
|
|
66
91
|
| `currentFee` | `number` | Current MEV fee in uniBps (decays from 800000→400000) |
|
|
67
92
|
|
|
68
|
-
### Step 2:
|
|
93
|
+
### Step 2: Get Pool Key and Determine Swap Direction
|
|
69
94
|
|
|
70
95
|
```typescript
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
console.log("Starting fee:", feeConfig.startingFee); // 800000 (80%)
|
|
74
|
-
console.log("Ending fee:", feeConfig.endingFee); // 400000 (40%)
|
|
75
|
-
console.log("Seconds to decay:", feeConfig.secondsToDecay); // 32n
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Step 3: Check Timing
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
// When did fee decay start?
|
|
82
|
-
const decayStart = await sdk.getAuctionDecayStartTime(poolId);
|
|
83
|
-
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
84
|
-
const elapsed = now - decayStart;
|
|
85
|
-
|
|
86
|
-
console.log("Seconds since decay started:", elapsed);
|
|
87
|
-
// If elapsed > secondsToDecay, fee is at the floor (endingFee)
|
|
88
|
-
|
|
89
|
-
// How many rounds total?
|
|
90
|
-
const maxRounds = await sdk.getAuctionMaxRounds();
|
|
91
|
-
console.log("Max auction rounds:", maxRounds);
|
|
96
|
+
const rewards = await sdk.getTokenRewards(tokenAddress);
|
|
97
|
+
const poolKey = rewards.poolKey;
|
|
92
98
|
|
|
93
|
-
//
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// If currentBlock < nextAuctionBlock, the current round is still active
|
|
99
|
+
// Determine swap direction from token sort order
|
|
100
|
+
const zeroForOne = poolKey.currency0.toLowerCase() === EXTERNAL.WETH.toLowerCase();
|
|
101
|
+
// true = WETH is currency0, buying token (most common)
|
|
102
|
+
// false = token is currency0, buying with WETH from currency1 side
|
|
98
103
|
```
|
|
99
104
|
|
|
100
|
-
### Step
|
|
105
|
+
### Step 3: Calculate Gas Price for Your Bid
|
|
101
106
|
|
|
102
107
|
```typescript
|
|
103
|
-
const desiredBidAmount = parseEther("0.
|
|
108
|
+
const desiredBidAmount = parseEther("0.001"); // How much ETH you want to bid
|
|
104
109
|
|
|
105
110
|
// SDK calculates the exact gas price needed
|
|
106
111
|
const requiredGasPrice = await sdk.getAuctionGasPriceForBid(
|
|
@@ -109,44 +114,50 @@ const requiredGasPrice = await sdk.getAuctionGasPriceForBid(
|
|
|
109
114
|
);
|
|
110
115
|
|
|
111
116
|
console.log("Required gas price:", requiredGasPrice);
|
|
112
|
-
// This is the maxFeePerGas you must set on your transaction
|
|
113
117
|
```
|
|
114
118
|
|
|
115
|
-
**The formula:** `bidAmount = (txGasPrice - gasPeg) * paymentPerGasUnit`. The utility contract solves for `txGasPrice` given your desired `bidAmount`.
|
|
119
|
+
**The formula:** `bidAmount = (txGasPrice - gasPeg) * paymentPerGasUnit` where `paymentPerGasUnit = 0.0001 ETH (1e14 wei)`. The utility contract solves for `txGasPrice` given your desired `bidAmount`.
|
|
116
120
|
|
|
117
|
-
### Step
|
|
121
|
+
### Step 4: Wait for the Auction Block
|
|
118
122
|
|
|
119
123
|
```typescript
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
const
|
|
124
|
+
// Poll until we're one block before the auction
|
|
125
|
+
while (true) {
|
|
126
|
+
const currentBlock = await publicClient.getBlockNumber();
|
|
127
|
+
const gap = Number(auction.nextAuctionBlock - currentBlock);
|
|
128
|
+
|
|
129
|
+
if (gap <= 0) {
|
|
130
|
+
console.log("Missed this round");
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
if (gap === 1) {
|
|
134
|
+
console.log("Next block is auction — fire!");
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
123
137
|
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// .fee — fee tier
|
|
128
|
-
// .tickSpacing — tick spacing (200)
|
|
129
|
-
// .hooks — hook contract address
|
|
138
|
+
// Wait ~2s (Base block time)
|
|
139
|
+
await new Promise(r => setTimeout(r, gap > 2 ? 500 : 200));
|
|
140
|
+
}
|
|
130
141
|
```
|
|
131
142
|
|
|
132
|
-
### Step
|
|
143
|
+
### Step 5: Execute the Bid
|
|
133
144
|
|
|
134
145
|
```typescript
|
|
146
|
+
// The SDK handles WETH wrapping + approval automatically
|
|
135
147
|
const result = await sdk.bidInAuction(
|
|
136
148
|
{
|
|
137
149
|
poolKey: rewards.poolKey,
|
|
138
|
-
zeroForOne
|
|
139
|
-
amountIn: parseEther("0.
|
|
140
|
-
amountOutMinimum: 0n,
|
|
141
|
-
round: auction.round,
|
|
142
|
-
bidAmount: desiredBidAmount,
|
|
150
|
+
zeroForOne, // determined in step 2
|
|
151
|
+
amountIn: parseEther("0.001"), // WETH to swap (auto-wrapped from ETH)
|
|
152
|
+
amountOutMinimum: 0n, // set slippage protection in production!
|
|
153
|
+
round: auction.round, // must match current on-chain round
|
|
154
|
+
bidAmount: desiredBidAmount, // ETH bid (sent as msg.value)
|
|
143
155
|
},
|
|
144
|
-
requiredGasPrice,
|
|
156
|
+
requiredGasPrice, // from step 3
|
|
145
157
|
);
|
|
146
158
|
|
|
147
159
|
console.log("Bid tx:", result.txHash);
|
|
148
160
|
|
|
149
|
-
// Wait for confirmation
|
|
150
161
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: result.txHash });
|
|
151
162
|
console.log("Status:", receipt.status); // "success" or "reverted"
|
|
152
163
|
```
|
|
@@ -157,7 +168,7 @@ console.log("Status:", receipt.status); // "success" or "reverted"
|
|
|
157
168
|
import { createPublicClient, createWalletClient, http, parseEther, formatEther } from "viem";
|
|
158
169
|
import { base } from "viem/chains";
|
|
159
170
|
import { privateKeyToAccount } from "viem/accounts";
|
|
160
|
-
import { LiquidSDK } from "liquid-sdk";
|
|
171
|
+
import { LiquidSDK, EXTERNAL, ERC20Abi } from "liquid-sdk";
|
|
161
172
|
|
|
162
173
|
async function snipeToken(tokenAddress: `0x${string}`, bidETH: string, swapETH: string) {
|
|
163
174
|
const account = privateKeyToAccount(PRIVATE_KEY);
|
|
@@ -183,21 +194,31 @@ async function snipeToken(tokenAddress: `0x${string}`, bidETH: string, swapETH:
|
|
|
183
194
|
return;
|
|
184
195
|
}
|
|
185
196
|
|
|
186
|
-
// 4. Get pool key
|
|
197
|
+
// 4. Get pool key and determine swap direction
|
|
187
198
|
const rewards = await sdk.getTokenRewards(tokenAddress);
|
|
199
|
+
const zeroForOne = rewards.poolKey.currency0.toLowerCase() === EXTERNAL.WETH.toLowerCase();
|
|
188
200
|
|
|
189
201
|
// 5. Calculate gas price for desired bid
|
|
190
202
|
const bidAmount = parseEther(bidETH);
|
|
191
203
|
const gasPrice = await sdk.getAuctionGasPriceForBid(auction.gasPeg, bidAmount);
|
|
192
204
|
|
|
193
|
-
console.log(`Bid
|
|
194
|
-
console.log(`
|
|
205
|
+
console.log(`Bid: ${formatEther(bidAmount)} ETH | Swap: ${swapETH} ETH`);
|
|
206
|
+
console.log(`Gas price: ${gasPrice} (peg: ${auction.gasPeg})`);
|
|
195
207
|
|
|
196
|
-
// 6.
|
|
208
|
+
// 6. Wait for the auction block
|
|
209
|
+
while (true) {
|
|
210
|
+
const currentBlock = await publicClient.getBlockNumber();
|
|
211
|
+
const gap = Number(auction.nextAuctionBlock - currentBlock);
|
|
212
|
+
if (gap <= 0) { console.log("Missed this round"); return; }
|
|
213
|
+
if (gap === 1) break; // next block is auction — fire!
|
|
214
|
+
await new Promise(r => setTimeout(r, gap > 2 ? 500 : 200));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 7. Execute the bid (SDK auto-wraps WETH + approves SniperUtil)
|
|
197
218
|
const result = await sdk.bidInAuction(
|
|
198
219
|
{
|
|
199
220
|
poolKey: rewards.poolKey,
|
|
200
|
-
zeroForOne
|
|
221
|
+
zeroForOne,
|
|
201
222
|
amountIn: parseEther(swapETH),
|
|
202
223
|
amountOutMinimum: 0n, // In production, calculate proper slippage!
|
|
203
224
|
round: auction.round,
|
|
@@ -208,19 +229,43 @@ async function snipeToken(tokenAddress: `0x${string}`, bidETH: string, swapETH:
|
|
|
208
229
|
|
|
209
230
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: result.txHash });
|
|
210
231
|
console.log(`Bid ${receipt.status === "success" ? "WON" : "FAILED"}: ${result.txHash}`);
|
|
232
|
+
|
|
233
|
+
if (receipt.status === "success") {
|
|
234
|
+
const tokenBal = await publicClient.readContract({
|
|
235
|
+
address: tokenAddress,
|
|
236
|
+
abi: ERC20Abi,
|
|
237
|
+
functionName: "balanceOf",
|
|
238
|
+
args: [account.address],
|
|
239
|
+
});
|
|
240
|
+
console.log(`Tokens received: ${formatEther(tokenBal as bigint)}`);
|
|
241
|
+
}
|
|
211
242
|
}
|
|
212
243
|
|
|
213
|
-
// Usage
|
|
214
|
-
await snipeToken("0x...", "0.
|
|
244
|
+
// Usage: bid 0.001 ETH, swap 0.001 ETH for tokens
|
|
245
|
+
await snipeToken("0x...", "0.001", "0.001");
|
|
215
246
|
```
|
|
216
247
|
|
|
248
|
+
## The Working Bid Flow (Summary)
|
|
249
|
+
|
|
250
|
+
1. Get auction state (`getAuctionState`) — need `gasPeg`, `round`, `nextAuctionBlock`
|
|
251
|
+
2. Get pool key (`getTokenRewards`) — need `poolKey` for the swap
|
|
252
|
+
3. Determine `zeroForOne` from pool key token sort order
|
|
253
|
+
4. Calculate gas price (`getAuctionGasPriceForBid`)
|
|
254
|
+
5. Wait until `currentBlock === nextAuctionBlock - 1`
|
|
255
|
+
6. Call `sdk.bidInAuction(params, gasPrice)` — SDK handles:
|
|
256
|
+
- Auto-wrapping ETH → WETH for `amountIn`
|
|
257
|
+
- Auto-approving SniperUtilV2 for WETH
|
|
258
|
+
- Setting `gas: 800_000n` (skipping estimation)
|
|
259
|
+
- Setting `maxFeePerGas` and `maxPriorityFeePerGas` to the calculated value
|
|
260
|
+
7. Transaction lands in `nextAuctionBlock` → snipe complete
|
|
261
|
+
|
|
217
262
|
## BidInAuctionParams Reference
|
|
218
263
|
|
|
219
264
|
```typescript
|
|
220
265
|
interface BidInAuctionParams {
|
|
221
|
-
poolKey: PoolKey; //
|
|
222
|
-
zeroForOne: boolean; // true
|
|
223
|
-
amountIn: bigint; //
|
|
266
|
+
poolKey: PoolKey; // Uniswap V4 pool key (get from getTokenRewards)
|
|
267
|
+
zeroForOne: boolean; // true if WETH is currency0 (buying token)
|
|
268
|
+
amountIn: bigint; // WETH to swap — pulled via transferFrom (auto-wrapped by SDK)
|
|
224
269
|
amountOutMinimum: bigint;// Minimum output (slippage protection)
|
|
225
270
|
round: bigint; // Must match current on-chain auction round
|
|
226
271
|
bidAmount: bigint; // ETH bid amount (sent as msg.value)
|
|
@@ -231,15 +276,18 @@ interface BidInAuctionResult {
|
|
|
231
276
|
}
|
|
232
277
|
```
|
|
233
278
|
|
|
234
|
-
## Auction
|
|
279
|
+
## Auction Constants (Current Deployment)
|
|
235
280
|
|
|
236
281
|
| Parameter | Value | Description |
|
|
237
282
|
|-----------|-------|-------------|
|
|
283
|
+
| Max rounds | 5 | Total auction rounds per token |
|
|
284
|
+
| Blocks between auctions | 2 | Rounds occur every 2 blocks |
|
|
285
|
+
| Blocks before first auction | 2 | First auction = deploy block + 2 |
|
|
286
|
+
| Payment per gas unit | 0.0001 ETH (1e14 wei) | Converts gas delta to bid ETH |
|
|
238
287
|
| Starting fee | 800,000 (80%) | Fee at auction start |
|
|
239
|
-
| Ending fee | 400,000 (40%) | Fee after decay
|
|
288
|
+
| Ending fee | 400,000 (40%) | Fee floor after decay |
|
|
240
289
|
| Decay period | 32 seconds | Time for fee to decay from start to end |
|
|
241
|
-
| Gas peg |
|
|
242
|
-
| Max rounds | Contract-defined | Total auction rounds per token |
|
|
290
|
+
| Gas peg | ~6.3M wei (dynamic) | Set at pool creation, equals Base baseFee |
|
|
243
291
|
|
|
244
292
|
## Timing Strategy
|
|
245
293
|
|
|
@@ -247,32 +295,23 @@ The auction fee **decays over time**, so there's a tradeoff:
|
|
|
247
295
|
|
|
248
296
|
- **Bid early** (high fee): You pay up to 80% of the swap as a fee, but you get the tokens before others. Useful if you expect rapid price appreciation.
|
|
249
297
|
- **Bid late** (lower fee): The fee decays to 40% over 32 seconds. You pay less in fees but risk being outbid or missing the auction window.
|
|
250
|
-
- **Wait for auction to end**: After all rounds complete, trading is at normal pool fees (typically 1%). No auction mechanics apply.
|
|
298
|
+
- **Wait for auction to end**: After all 5 rounds complete, trading is at normal pool fees (typically 1%). No auction mechanics apply.
|
|
251
299
|
|
|
252
300
|
```typescript
|
|
253
301
|
// Check current fee percentage
|
|
254
302
|
const feePercent = auction.currentFee / 10000; // e.g., 80.0, 60.5, 40.0
|
|
255
303
|
console.log(`Current fee: ${feePercent}%`);
|
|
256
|
-
|
|
257
|
-
// Check fee decay progress
|
|
258
|
-
const feeConfig = await sdk.getAuctionFeeConfig(poolId);
|
|
259
|
-
const decayStart = await sdk.getAuctionDecayStartTime(poolId);
|
|
260
|
-
const now = BigInt(Math.floor(Date.now() / 1000));
|
|
261
|
-
const decayProgress = Number(now - decayStart) / Number(feeConfig.secondsToDecay);
|
|
262
|
-
console.log(`Decay progress: ${Math.min(decayProgress * 100, 100).toFixed(1)}%`);
|
|
263
304
|
```
|
|
264
305
|
|
|
265
|
-
##
|
|
266
|
-
|
|
267
|
-
1. **`round` must be current**: If you submit a bid with a stale round number, the transaction will revert. Always fetch `getAuctionState()` right before bidding.
|
|
268
|
-
|
|
269
|
-
2. **Gas price is the bid**: The auction uses `tx.gasprice` as the bidding mechanism. The SDK's `bidInAuction()` sets `maxFeePerGas` to the calculated value. On Base (L2), gas prices are low, so even small bids produce manageable gas costs.
|
|
270
|
-
|
|
271
|
-
3. **Slippage protection**: Set `amountOutMinimum` to a non-zero value in production. Calculate it based on the current pool price and your acceptable slippage tolerance.
|
|
272
|
-
|
|
273
|
-
4. **The bid amount is sent as `msg.value`**: This ETH goes to the auction contract, not to the swap. The `amountIn` is the separate ETH amount for the actual token swap.
|
|
306
|
+
## Common Errors
|
|
274
307
|
|
|
275
|
-
|
|
308
|
+
| Error | Selector | Cause | Fix |
|
|
309
|
+
|-------|----------|-------|-----|
|
|
310
|
+
| `GasPriceTooLow()` | `0x8c19df83` | `tx.gasprice ≤ gasPeg` | Use `getAuctionGasPriceForBid()` and set both `maxFeePerGas` + `maxPriorityFeePerGas` |
|
|
311
|
+
| `Unauthorized()` | `0x82b42900` | Fee Locker hasn't authorized the Sniper Auction as depositor | Protocol admin must call `FeeLocker.addDepositor(SniperAuctionAddress)` |
|
|
312
|
+
| `NotAuctionBlock()` | — | Tx didn't land in `nextAuctionBlock` | Submit 1 block early, tx must mine in the exact auction block |
|
|
313
|
+
| WETH `transferFrom` revert | — | Insufficient WETH balance or allowance | SDK handles this automatically; ensure enough ETH for wrap |
|
|
314
|
+
| Gas estimation failure | — | `eth_estimateGas` runs at baseFee < gasPeg | SDK sets `gas: 800_000n` manually |
|
|
276
315
|
|
|
277
316
|
## Read-Only Auction Queries (No Wallet Needed)
|
|
278
317
|
|
|
@@ -283,7 +322,7 @@ const auction = await sdk.getAuctionState(poolId);
|
|
|
283
322
|
const feeConfig = await sdk.getAuctionFeeConfig(poolId);
|
|
284
323
|
const decayStart = await sdk.getAuctionDecayStartTime(poolId);
|
|
285
324
|
const maxRounds = await sdk.getAuctionMaxRounds();
|
|
286
|
-
const gasPrice = await sdk.getAuctionGasPriceForBid(auction.gasPeg, parseEther("0.
|
|
325
|
+
const gasPrice = await sdk.getAuctionGasPriceForBid(auction.gasPeg, parseEther("0.001"));
|
|
287
326
|
```
|
|
288
327
|
|
|
289
328
|
## Contract Addresses
|
|
@@ -291,6 +330,6 @@ const gasPrice = await sdk.getAuctionGasPriceForBid(auction.gasPeg, parseEther("
|
|
|
291
330
|
```typescript
|
|
292
331
|
import { ADDRESSES } from "liquid-sdk";
|
|
293
332
|
|
|
294
|
-
ADDRESSES.SNIPER_AUCTION_V2 // Auction state contract
|
|
295
|
-
ADDRESSES.SNIPER_UTIL_V2 // Bid execution contract
|
|
333
|
+
ADDRESSES.SNIPER_AUCTION_V2 // 0x187e8627... — Auction state contract
|
|
334
|
+
ADDRESSES.SNIPER_UTIL_V2 // 0x2B6cd5Be... — Bid execution contract
|
|
296
335
|
```
|