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 CHANGED
@@ -428,10 +428,31 @@ const maxRounds = await sdk.getAuctionMaxRounds();
428
428
  ```typescript
429
429
  const gasPrice = await sdk.getAuctionGasPriceForBid(
430
430
  auction.gasPeg,
431
- parseEther("1"), // desired bid
431
+ parseEther("0.001"), // desired bid
432
432
  );
433
433
  ```
434
434
 
435
+ #### `sdk.bidInAuction(params, gasPrice)` — Bid in auction and swap tokens
436
+
437
+ Requires wallet. Auto-wraps ETH → WETH and approves SniperUtilV2 if needed. Sets gas manually (800K) and both `maxFeePerGas`/`maxPriorityFeePerGas` to the auction gas price.
438
+
439
+ ```typescript
440
+ const rewards = await sdk.getTokenRewards(tokenAddress);
441
+ const zeroForOne = rewards.poolKey.currency0.toLowerCase() === EXTERNAL.WETH.toLowerCase();
442
+
443
+ const result = await sdk.bidInAuction({
444
+ poolKey: rewards.poolKey,
445
+ zeroForOne, // depends on token sort order vs WETH
446
+ amountIn: parseEther("0.001"), // WETH to swap (auto-wrapped from ETH)
447
+ amountOutMinimum: 0n, // set slippage in production
448
+ round: auction.round, // must match current on-chain round
449
+ bidAmount: parseEther("0.0005"), // ETH bid (sent as msg.value)
450
+ }, gasPrice);
451
+ // result.txHash — transaction hash
452
+ ```
453
+
454
+ **Important:** The bid is valid only at `nextAuctionBlock`. Submit when `currentBlock === nextAuctionBlock - 1`. The `amountIn` is pulled from your WETH balance (separate from the bid's `msg.value`). Auction runs 5 rounds, every 2 blocks, starting 2 blocks after deployment.
455
+
435
456
  ---
436
457
 
437
458
  ### MEV Protection
package/dist/index.d.mts CHANGED
@@ -200,9 +200,16 @@ interface LiquidSDKConfig {
200
200
  interface BidInAuctionParams {
201
201
  /** The pool key identifying the token's Uniswap V4 pool */
202
202
  poolKey: PoolKey;
203
- /** True if swapping token0 → token1 (typically ETH → token) */
203
+ /**
204
+ * Swap direction. Set `true` when WETH is currency0 (buying token with ETH).
205
+ * Determine via: `poolKey.currency0.toLowerCase() === WETH.toLowerCase()`
206
+ */
204
207
  zeroForOne: boolean;
205
- /** Amount of input token (in wei) */
208
+ /**
209
+ * Amount of WETH to swap (in wei). Pulled from caller's WETH balance via
210
+ * `transferFrom` — separate from the bid. The SDK auto-wraps ETH → WETH
211
+ * and approves SniperUtilV2 if balance or allowance is insufficient.
212
+ */
206
213
  amountIn: bigint;
207
214
  /** Minimum output tokens to receive (slippage protection) */
208
215
  amountOutMinimum: bigint;
@@ -267,22 +274,30 @@ declare class LiquidSDK {
267
274
  * The auction lets bidders compete via gas price — the bid amount is
268
275
  * determined by how much your tx.gasprice exceeds the pool's gasPeg.
269
276
  *
277
+ * **Important:** The `amountIn` (swap input) is pulled from the caller's
278
+ * WETH balance via `transferFrom`. The SDK automatically wraps ETH → WETH
279
+ * and approves the SniperUtilV2 if needed. The `bidAmount` is sent as
280
+ * `msg.value` (separate from the swap).
281
+ *
282
+ * Gas price must exceed the pool's `gasPeg` — the delta encodes the bid.
283
+ * Both `maxFeePerGas` and `maxPriorityFeePerGas` are set to ensure the
284
+ * effective gas price matches on Base (EIP-1559). Gas estimation is skipped
285
+ * because `eth_estimateGas` simulates at `baseFee` which is below `gasPeg`.
286
+ *
270
287
  * @example
271
288
  * ```typescript
272
- * // 1. Get auction state
289
+ * // 1. Get auction state & pool key
273
290
  * const state = await sdk.getAuctionState(poolId);
291
+ * const rewards = await sdk.getTokenRewards(tokenAddress);
274
292
  *
275
293
  * // 2. Calculate gas price for desired bid
276
294
  * const gasPrice = await sdk.getAuctionGasPriceForBid(state.gasPeg, bidAmount);
277
295
  *
278
- * // 3. Get pool key from token rewards
279
- * const rewards = await sdk.getTokenRewards(tokenAddress);
280
- *
281
- * // 4. Bid
296
+ * // 3. Bid (SDK auto-wraps WETH + approves if needed)
282
297
  * const result = await sdk.bidInAuction({
283
298
  * poolKey: rewards.poolKey,
284
299
  * zeroForOne: true, // ETH → token
285
- * amountIn: parseEther("0.1"), // swap 0.1 ETH
300
+ * amountIn: parseEther("0.1"), // swap 0.1 ETH (pulled from WETH balance)
286
301
  * amountOutMinimum: 0n, // set slippage
287
302
  * round: state.round,
288
303
  * bidAmount: parseEther("0.01"),
package/dist/index.d.ts CHANGED
@@ -200,9 +200,16 @@ interface LiquidSDKConfig {
200
200
  interface BidInAuctionParams {
201
201
  /** The pool key identifying the token's Uniswap V4 pool */
202
202
  poolKey: PoolKey;
203
- /** True if swapping token0 → token1 (typically ETH → token) */
203
+ /**
204
+ * Swap direction. Set `true` when WETH is currency0 (buying token with ETH).
205
+ * Determine via: `poolKey.currency0.toLowerCase() === WETH.toLowerCase()`
206
+ */
204
207
  zeroForOne: boolean;
205
- /** Amount of input token (in wei) */
208
+ /**
209
+ * Amount of WETH to swap (in wei). Pulled from caller's WETH balance via
210
+ * `transferFrom` — separate from the bid. The SDK auto-wraps ETH → WETH
211
+ * and approves SniperUtilV2 if balance or allowance is insufficient.
212
+ */
206
213
  amountIn: bigint;
207
214
  /** Minimum output tokens to receive (slippage protection) */
208
215
  amountOutMinimum: bigint;
@@ -267,22 +274,30 @@ declare class LiquidSDK {
267
274
  * The auction lets bidders compete via gas price — the bid amount is
268
275
  * determined by how much your tx.gasprice exceeds the pool's gasPeg.
269
276
  *
277
+ * **Important:** The `amountIn` (swap input) is pulled from the caller's
278
+ * WETH balance via `transferFrom`. The SDK automatically wraps ETH → WETH
279
+ * and approves the SniperUtilV2 if needed. The `bidAmount` is sent as
280
+ * `msg.value` (separate from the swap).
281
+ *
282
+ * Gas price must exceed the pool's `gasPeg` — the delta encodes the bid.
283
+ * Both `maxFeePerGas` and `maxPriorityFeePerGas` are set to ensure the
284
+ * effective gas price matches on Base (EIP-1559). Gas estimation is skipped
285
+ * because `eth_estimateGas` simulates at `baseFee` which is below `gasPeg`.
286
+ *
270
287
  * @example
271
288
  * ```typescript
272
- * // 1. Get auction state
289
+ * // 1. Get auction state & pool key
273
290
  * const state = await sdk.getAuctionState(poolId);
291
+ * const rewards = await sdk.getTokenRewards(tokenAddress);
274
292
  *
275
293
  * // 2. Calculate gas price for desired bid
276
294
  * const gasPrice = await sdk.getAuctionGasPriceForBid(state.gasPeg, bidAmount);
277
295
  *
278
- * // 3. Get pool key from token rewards
279
- * const rewards = await sdk.getTokenRewards(tokenAddress);
280
- *
281
- * // 4. Bid
296
+ * // 3. Bid (SDK auto-wraps WETH + approves if needed)
282
297
  * const result = await sdk.bidInAuction({
283
298
  * poolKey: rewards.poolKey,
284
299
  * zeroForOne: true, // ETH → token
285
- * amountIn: parseEther("0.1"), // swap 0.1 ETH
300
+ * amountIn: parseEther("0.1"), // swap 0.1 ETH (pulled from WETH balance)
286
301
  * amountOutMinimum: 0n, // set slippage
287
302
  * round: state.round,
288
303
  * bidAmount: parseEther("0.01"),
package/dist/index.js CHANGED
@@ -1631,22 +1631,30 @@ var LiquidSDK = class {
1631
1631
  * The auction lets bidders compete via gas price — the bid amount is
1632
1632
  * determined by how much your tx.gasprice exceeds the pool's gasPeg.
1633
1633
  *
1634
+ * **Important:** The `amountIn` (swap input) is pulled from the caller's
1635
+ * WETH balance via `transferFrom`. The SDK automatically wraps ETH → WETH
1636
+ * and approves the SniperUtilV2 if needed. The `bidAmount` is sent as
1637
+ * `msg.value` (separate from the swap).
1638
+ *
1639
+ * Gas price must exceed the pool's `gasPeg` — the delta encodes the bid.
1640
+ * Both `maxFeePerGas` and `maxPriorityFeePerGas` are set to ensure the
1641
+ * effective gas price matches on Base (EIP-1559). Gas estimation is skipped
1642
+ * because `eth_estimateGas` simulates at `baseFee` which is below `gasPeg`.
1643
+ *
1634
1644
  * @example
1635
1645
  * ```typescript
1636
- * // 1. Get auction state
1646
+ * // 1. Get auction state & pool key
1637
1647
  * const state = await sdk.getAuctionState(poolId);
1648
+ * const rewards = await sdk.getTokenRewards(tokenAddress);
1638
1649
  *
1639
1650
  * // 2. Calculate gas price for desired bid
1640
1651
  * const gasPrice = await sdk.getAuctionGasPriceForBid(state.gasPeg, bidAmount);
1641
1652
  *
1642
- * // 3. Get pool key from token rewards
1643
- * const rewards = await sdk.getTokenRewards(tokenAddress);
1644
- *
1645
- * // 4. Bid
1653
+ * // 3. Bid (SDK auto-wraps WETH + approves if needed)
1646
1654
  * const result = await sdk.bidInAuction({
1647
1655
  * poolKey: rewards.poolKey,
1648
1656
  * zeroForOne: true, // ETH → token
1649
- * amountIn: parseEther("0.1"), // swap 0.1 ETH
1657
+ * amountIn: parseEther("0.1"), // swap 0.1 ETH (pulled from WETH balance)
1650
1658
  * amountOutMinimum: 0n, // set slippage
1651
1659
  * round: state.round,
1652
1660
  * bidAmount: parseEther("0.01"),
@@ -1657,6 +1665,44 @@ var LiquidSDK = class {
1657
1665
  if (!this.walletClient?.account) {
1658
1666
  throw new Error("walletClient with account required for bidInAuction");
1659
1667
  }
1668
+ const account = this.walletClient.account;
1669
+ const weth = EXTERNAL.WETH;
1670
+ const wethBalance = await this.publicClient.readContract({
1671
+ address: weth,
1672
+ abi: ERC20Abi,
1673
+ functionName: "balanceOf",
1674
+ args: [account.address]
1675
+ });
1676
+ if (wethBalance < params.amountIn) {
1677
+ const wrapAmount = params.amountIn - wethBalance;
1678
+ const wrapTx = await this.walletClient.writeContract({
1679
+ address: weth,
1680
+ abi: [{ type: "function", name: "deposit", inputs: [], outputs: [], stateMutability: "payable" }],
1681
+ functionName: "deposit",
1682
+ args: [],
1683
+ value: wrapAmount,
1684
+ chain: import_chains2.base,
1685
+ account
1686
+ });
1687
+ await this.publicClient.waitForTransactionReceipt({ hash: wrapTx });
1688
+ }
1689
+ const allowance = await this.publicClient.readContract({
1690
+ address: weth,
1691
+ abi: ERC20Abi,
1692
+ functionName: "allowance",
1693
+ args: [account.address, ADDRESSES.SNIPER_UTIL_V2]
1694
+ });
1695
+ if (allowance < params.amountIn) {
1696
+ const approveTx = await this.walletClient.writeContract({
1697
+ address: weth,
1698
+ abi: ERC20Abi,
1699
+ functionName: "approve",
1700
+ args: [ADDRESSES.SNIPER_UTIL_V2, params.amountIn * 10n],
1701
+ chain: import_chains2.base,
1702
+ account
1703
+ });
1704
+ await this.publicClient.waitForTransactionReceipt({ hash: approveTx });
1705
+ }
1660
1706
  const hookData = (0, import_viem2.encodeAbiParameters)(
1661
1707
  [
1662
1708
  {
@@ -1693,8 +1739,10 @@ var LiquidSDK = class {
1693
1739
  ],
1694
1740
  value: params.bidAmount,
1695
1741
  chain: import_chains2.base,
1696
- account: this.walletClient.account,
1697
- maxFeePerGas
1742
+ account,
1743
+ gas: 800000n,
1744
+ maxFeePerGas,
1745
+ maxPriorityFeePerGas: maxFeePerGas
1698
1746
  });
1699
1747
  return { txHash };
1700
1748
  }