liquid-sdk 1.7.2 → 1.7.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 +16 -13
- package/CHANGELOG.md +22 -0
- package/dist/index.d.mts +95 -28
- package/dist/index.d.ts +95 -28
- package/dist/index.js +128 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +125 -3
- package/dist/index.mjs.map +1 -1
- package/llms.txt +3 -3
- package/package.json +1 -1
package/AGENT_README.md
CHANGED
|
@@ -35,7 +35,7 @@ No API keys, no backend, no database. The SDK talks directly to Base mainnet con
|
|
|
35
35
|
Liquid Protocol deploys ERC-20 tokens on Base with:
|
|
36
36
|
- Uniswap V4 liquidity pools (automatic)
|
|
37
37
|
- LP fee collection and reward distribution
|
|
38
|
-
- MEV protection via
|
|
38
|
+
- MEV protection via sniper auction
|
|
39
39
|
- Optional extensions: dev buy, vault lockup/vesting, airdrops
|
|
40
40
|
|
|
41
41
|
Every token gets 100 billion supply (18 decimals), a Uniswap V4 pool, and locked liquidity with configurable reward splits.
|
|
@@ -161,7 +161,7 @@ const txHash = await sdk.collectRewardsWithoutUnlock(tokenAddress);
|
|
|
161
161
|
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
-
**Important:** After deployment, the
|
|
164
|
+
**Important:** After deployment, the sniper auction MEV module may block early reward collection. If `collectRewardsWithoutUnlock` reverts with `ManagerLocked`, wait for the auction period to end.
|
|
165
165
|
|
|
166
166
|
#### `sdk.updateRewardRecipient(tokenAddress, rewardIndex, newRecipient)` — Change reward recipient
|
|
167
167
|
|
|
@@ -455,21 +455,23 @@ const result = await sdk.bidInAuction({
|
|
|
455
455
|
|
|
456
456
|
---
|
|
457
457
|
|
|
458
|
-
### MEV
|
|
458
|
+
### MEV Descending Fees
|
|
459
459
|
|
|
460
|
-
#### `sdk.
|
|
460
|
+
#### `sdk.getMevDescendingFeesBlockDelay()` — Configured block delay
|
|
461
461
|
|
|
462
462
|
```typescript
|
|
463
|
-
const delay = await sdk.
|
|
464
|
-
// delay: bigint — number of blocks
|
|
463
|
+
const delay = await sdk.getMevDescendingFeesBlockDelay();
|
|
464
|
+
// delay: bigint — number of blocks the MEV module fee window covers
|
|
465
465
|
```
|
|
466
466
|
|
|
467
|
-
|
|
467
|
+
`sdk.getMevBlockDelay()` is a deprecated alias for the same call.
|
|
468
|
+
|
|
469
|
+
#### `sdk.getPoolUnlockTime(poolId)` — When MEV lock expires
|
|
468
470
|
|
|
469
471
|
```typescript
|
|
470
472
|
const unlockTime = await sdk.getPoolUnlockTime(poolId);
|
|
471
|
-
// unlockTime
|
|
472
|
-
//
|
|
473
|
+
// If Date.now()/1000 < unlockTime, the pool is still inside the MEV window
|
|
474
|
+
// and writes that go through the MevDescendingFees hook may revert with ManagerLocked.
|
|
473
475
|
```
|
|
474
476
|
|
|
475
477
|
---
|
|
@@ -516,9 +518,9 @@ When calling `deployToken`, all fields except `name` and `symbol` are optional.
|
|
|
516
518
|
| `rewardAdmins` | `[walletAddress]` | Deployer is admin |
|
|
517
519
|
| `rewardRecipients` | `[walletAddress]` | Deployer gets rewards |
|
|
518
520
|
| `rewardBps` | `[10000]` | 100% to deployer |
|
|
519
|
-
| `tickLower` | `[-230400, -
|
|
520
|
-
| `tickUpper` | `[-
|
|
521
|
-
| `positionBps` | `[
|
|
521
|
+
| `tickLower` | `[-230400, -216000, -202000, -155000, -141000]` | 5-position Liquid layout |
|
|
522
|
+
| `tickUpper` | `[-216000, -155000, -155000, -120000, -120000]` | 5-position Liquid layout |
|
|
523
|
+
| `positionBps` | `[1000, 5000, 1500, 2000, 500]` | 10% / 50% / 15% / 20% / 5% |
|
|
522
524
|
| `mevModule` | `ADDRESSES.SNIPER_AUCTION_V2` | 80%→40% over 20s |
|
|
523
525
|
| `extensions` | `[]` | No extensions |
|
|
524
526
|
|
|
@@ -587,7 +589,8 @@ import {
|
|
|
587
589
|
LiquidSniperUtilV2Abi,
|
|
588
590
|
LiquidAirdropV2Abi,
|
|
589
591
|
LiquidPoolExtensionAllowlistAbi,
|
|
590
|
-
|
|
592
|
+
LiquidMevDescendingFeesAbi,
|
|
593
|
+
LiquidMevBlockDelayAbi, // deprecated alias — prefer LiquidMevDescendingFeesAbi
|
|
591
594
|
LiquidLpLockerAbi,
|
|
592
595
|
ERC20Abi,
|
|
593
596
|
} from "liquid-sdk";
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `liquid-sdk` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.7.4] - 2026-04-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `EXTERNAL.DIEM` — the DIEM token address on Base, for DIEM-paired token launches.
|
|
9
|
+
- `shiftPositions(positions, shiftBy)` — re-anchor a fixed-shape position layout to a different starting tick, preserving `positionBps`.
|
|
10
|
+
- `createLiquidPositionsUSD(startingMarketCapUSD, pairedTokenPriceUSD, tickSpacing?)` — the canonical 5-position "Liquid" layout re-anchored to a starting market cap, denominated in the *paired token's* USD price. Works for any pair token (WETH or DIEM); unlike `createDefaultPositions` (3-tranche), it preserves the exact `POOL_POSITIONS.Liquid` curve `deployToken()` uses by default.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `deployToken` gas estimation no longer silently swallows on-chain revert errors. Previously a failing `eth_estimateGas` (e.g., insufficient msg.value, paused factory, pre-flight check revert) would be caught and replaced with a 6M fallback, causing the tx to be broadcast and burn real gas for nothing. Now a revert-shaped error bubbles to the caller; only transport-level failures fall back. Non-revert fallbacks log a warning via `console.warn`.
|
|
14
|
+
|
|
15
|
+
## [1.7.3] - 2026-04-22
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- `buildAirdropExtension({ admin, merkleRoot, allocationBps, lockupDuration, vestingDuration })` — creates a `LiquidAirdropV2` extension config for use in `deployToken({ extensions: [...] })`. Double-hashed leaf format compatible with OpenZeppelin `MerkleProof`. Contract minimums enforced (1-day lockup, ≤90% allocation).
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- `deployToken` no longer uses a hard-coded `gas: 5_000_000n` — real mainnet deploys currently require ~5.04M gas. Now uses `estimateContractGas * 1.2` with a 6M fallback so the SDK auto-adjusts as the factory evolves. Previous versions could OOG on mainnet.
|
|
22
|
+
|
|
23
|
+
### Verified
|
|
24
|
+
- End-to-end airdrop flow fork-tested against Base mainnet (real `LiquidAirdropV2` at `0x1423974d48f525462f1c087cBFdCC20BDBc33CdD`): deploy → state register → claim with single-leaf proof all confirmed.
|
|
25
|
+
- Mainnet dry-run deploy confirmed on-chain state encoding: [basescan tx](https://basescan.org/tx/0x1807c1e3eb92ccb0c32779855cd35d5581e6143d4232f4ab66d39517ee86e3d0).
|
|
26
|
+
|
|
5
27
|
## [1.2.0] - 2025-03-10
|
|
6
28
|
|
|
7
29
|
### Added
|
package/dist/index.d.mts
CHANGED
|
@@ -63,6 +63,21 @@ interface VaultExtensionParams {
|
|
|
63
63
|
/** Vesting duration in seconds after lockup ends (0 = no vesting, tokens unlock all at once) */
|
|
64
64
|
vestingDuration?: number;
|
|
65
65
|
}
|
|
66
|
+
interface AirdropExtensionParams {
|
|
67
|
+
/** Address allowed to `updateAdmin`, `updateMerkleRoot` (under conditions),
|
|
68
|
+
* and `adminClaim` the remainder after claim expiration. */
|
|
69
|
+
admin: Address;
|
|
70
|
+
/** Merkle root over leaves `keccak256(bytes.concat(keccak256(abi.encode(
|
|
71
|
+
* recipient, allocatedAmount))))`. Double-hashed per OZ convention. */
|
|
72
|
+
merkleRoot: Hex;
|
|
73
|
+
/** Percentage of supply to reserve for the airdrop, in BPS (1–9000). */
|
|
74
|
+
allocationBps: number;
|
|
75
|
+
/** Lockup in seconds before any recipient can claim. Min 86400 (1 day). */
|
|
76
|
+
lockupDuration: number;
|
|
77
|
+
/** Linear vesting after lockup. 0 = instant claim of full entitlement at
|
|
78
|
+
* lockup end. */
|
|
79
|
+
vestingDuration?: number;
|
|
80
|
+
}
|
|
66
81
|
interface DeployTokenParams {
|
|
67
82
|
name: string;
|
|
68
83
|
symbol: string;
|
|
@@ -270,6 +285,29 @@ declare class LiquidSDK {
|
|
|
270
285
|
* ```
|
|
271
286
|
*/
|
|
272
287
|
buildVaultExtension(vault: VaultExtensionParams): ExtensionConfig;
|
|
288
|
+
/**
|
|
289
|
+
* Build an ExtensionConfig that reserves a percentage of supply into
|
|
290
|
+
* the LiquidAirdropV2 contract for merkle-tree-based distribution.
|
|
291
|
+
*
|
|
292
|
+
* The airdrop contract expects `AirdropV2ExtensionData`:
|
|
293
|
+
* { address admin, bytes32 merkleRoot, uint256 lockupDuration, uint256 vestingDuration }
|
|
294
|
+
*
|
|
295
|
+
* Leaf encoding used by LiquidAirdropV2.claim (note: **double hashed**
|
|
296
|
+
* — OZ's standard 2nd-preimage-resistant pattern):
|
|
297
|
+
* leaf = keccak256(bytes.concat(keccak256(abi.encode(recipient, allocatedAmount))))
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const airdropExt = sdk.buildAirdropExtension({
|
|
302
|
+
* admin: account.address,
|
|
303
|
+
* merkleRoot: "0x…",
|
|
304
|
+
* allocationBps: 2000, // 20%
|
|
305
|
+
* lockupDuration: 86400, // 1 day (minimum)
|
|
306
|
+
* vestingDuration: 0, // instant claim after lockup
|
|
307
|
+
* });
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
buildAirdropExtension(airdrop: AirdropExtensionParams): ExtensionConfig;
|
|
273
311
|
/**
|
|
274
312
|
* Validate a DeploymentConfig before sending to the contract.
|
|
275
313
|
* Catches common mistakes client-side with clear error messages.
|
|
@@ -433,6 +471,9 @@ declare const ADDRESSES: {
|
|
|
433
471
|
declare const EXTERNAL: {
|
|
434
472
|
readonly POOL_MANAGER: Address;
|
|
435
473
|
readonly WETH: Address;
|
|
474
|
+
/** DIEM — Liquid's intelligence-economy token. Also a pair token for
|
|
475
|
+
* agent-token launches (see `createLiquidPositionsUSD`). */
|
|
476
|
+
readonly DIEM: Address;
|
|
436
477
|
readonly UNIVERSAL_ROUTER: Address;
|
|
437
478
|
readonly PERMIT2: Address;
|
|
438
479
|
};
|
|
@@ -489,7 +530,7 @@ declare const POOL_POSITIONS: {
|
|
|
489
530
|
*/
|
|
490
531
|
declare const DEFAULTS: {
|
|
491
532
|
readonly HOOK: `0x${string}`;
|
|
492
|
-
/** LP Locker with fee conversion (converts fees to
|
|
533
|
+
/** LP Locker with fee conversion (converts fees to WETH before distributing) */
|
|
493
534
|
readonly LOCKER: `0x${string}`;
|
|
494
535
|
readonly TICK_SPACING: 200;
|
|
495
536
|
readonly TICK_IF_TOKEN0_IS_LIQUID: -230400;
|
|
@@ -583,31 +624,7 @@ declare const DEFAULT_CHAIN: {
|
|
|
583
624
|
formatters: {
|
|
584
625
|
readonly block: {
|
|
585
626
|
exclude: [] | undefined;
|
|
586
|
-
format: (args: viem_chains.OpStackRpcBlock, action
|
|
587
|
-
/**
|
|
588
|
-
* Pre-built position configurations.
|
|
589
|
-
*
|
|
590
|
-
* - **Standard**: Single position covering full range (~$20K → $1.5B).
|
|
591
|
-
* Default starting tick -230400 (≈10 ETH market cap).
|
|
592
|
-
*
|
|
593
|
-
* - **Liquid**: 3-tranche default for Liquid Protocol.
|
|
594
|
-
* Hardcoded for ≈10 ETH start at ~$2070/ETH.
|
|
595
|
-
* For dynamic market cap targets, use `createPositionsUSD()` instead.
|
|
596
|
-
*
|
|
597
|
-
* Note: positionBps must sum to 10,000 (100%).
|
|
598
|
-
*/
|
|
599
|
-
? /**
|
|
600
|
-
* Pre-built position configurations.
|
|
601
|
-
*
|
|
602
|
-
* - **Standard**: Single position covering full range (~$20K → $1.5B).
|
|
603
|
-
* Default starting tick -230400 (≈10 ETH market cap).
|
|
604
|
-
*
|
|
605
|
-
* - **Liquid**: 3-tranche default for Liquid Protocol.
|
|
606
|
-
* Hardcoded for ≈10 ETH start at ~$2070/ETH.
|
|
607
|
-
* For dynamic market cap targets, use `createPositionsUSD()` instead.
|
|
608
|
-
*
|
|
609
|
-
* Note: positionBps must sum to 10,000 (100%).
|
|
610
|
-
*/: string | undefined) => {
|
|
627
|
+
format: (args: viem_chains.OpStackRpcBlock, action?: string | undefined) => {
|
|
611
628
|
baseFeePerGas: bigint | null;
|
|
612
629
|
blobGasUsed: bigint;
|
|
613
630
|
difficulty: bigint;
|
|
@@ -2285,6 +2302,7 @@ declare function getTickFromMarketCapStable(marketCap: number, stableDecimals: n
|
|
|
2285
2302
|
* market cap milestones. Percentages represent share of the *pool supply*
|
|
2286
2303
|
* (i.e. after dev buy, airdrop, and vault allocations are deducted).
|
|
2287
2304
|
*/
|
|
2305
|
+
|
|
2288
2306
|
interface MarketCapTranche {
|
|
2289
2307
|
/** Upper bound market cap in ETH for this tranche */
|
|
2290
2308
|
upperMarketCapETH: number;
|
|
@@ -2380,6 +2398,55 @@ declare function createPositionsUSD(startingMarketCapUSD: number, ethPriceUSD: n
|
|
|
2380
2398
|
declare function createDefaultPositions(startingMarketCapUSD: number, ethPriceUSD: number, tickSpacing?: number): PositionArrays & {
|
|
2381
2399
|
tickIfToken0IsLiquid: number;
|
|
2382
2400
|
};
|
|
2401
|
+
/**
|
|
2402
|
+
* Shift every tick in a position layout by a fixed amount, preserving the
|
|
2403
|
+
* positionBps splits. The primitive behind `createLiquidPositionsUSD` — it
|
|
2404
|
+
* re-anchors a fixed-shape layout (e.g. `POOL_POSITIONS.Liquid`) to a
|
|
2405
|
+
* different starting tick.
|
|
2406
|
+
*
|
|
2407
|
+
* `shiftBy` should be a multiple of the pool's tick spacing so the shifted
|
|
2408
|
+
* ticks stay aligned. A difference of two aligned ticks is always aligned,
|
|
2409
|
+
* so deriving it as `targetTick - sourceBottomTick` is safe.
|
|
2410
|
+
*
|
|
2411
|
+
* @param positions - Source positions (e.g. `POOL_POSITIONS.Liquid`)
|
|
2412
|
+
* @param shiftBy - Ticks to add to every tickLower/tickUpper (may be negative)
|
|
2413
|
+
* @returns A fresh array — the source is not mutated
|
|
2414
|
+
*/
|
|
2415
|
+
declare function shiftPositions(positions: readonly PoolPosition[], shiftBy: number): PoolPosition[];
|
|
2416
|
+
/**
|
|
2417
|
+
* Build the canonical 5-position "Liquid" layout (10/50/15/20/5) re-anchored
|
|
2418
|
+
* to a starting market cap, denominated in the *paired token's* USD price.
|
|
2419
|
+
*
|
|
2420
|
+
* Works for any pair token — pass the price of whatever the pool is paired
|
|
2421
|
+
* against:
|
|
2422
|
+
* - WETH-paired: `createLiquidPositionsUSD(20_000, ethPriceUSD)`
|
|
2423
|
+
* - DIEM-paired: `createLiquidPositionsUSD(20_000, diemPriceUSD)`
|
|
2424
|
+
*
|
|
2425
|
+
* Unlike `createDefaultPositions` (a 3-tranche layout), this preserves the
|
|
2426
|
+
* exact shape of `POOL_POSITIONS.Liquid` — the same curve `deployToken()`
|
|
2427
|
+
* uses by default — just shifted so its bottom sits at the requested start.
|
|
2428
|
+
*
|
|
2429
|
+
* @param startingMarketCapUSD - Initial market cap in USD
|
|
2430
|
+
* @param pairedTokenPriceUSD - USD price of the token the pool is paired against
|
|
2431
|
+
* @param tickSpacing - Tick spacing (default 200)
|
|
2432
|
+
* @returns Position arrays + `tickIfToken0IsLiquid`, ready to spread into `deployToken()`
|
|
2433
|
+
*
|
|
2434
|
+
* @example
|
|
2435
|
+
* ```ts
|
|
2436
|
+
* import { LiquidSDK, EXTERNAL, createLiquidPositionsUSD } from "liquid-sdk";
|
|
2437
|
+
*
|
|
2438
|
+
* const positions = createLiquidPositionsUSD(20_000, diemPriceUSD);
|
|
2439
|
+
* await sdk.deployToken({
|
|
2440
|
+
* name: "Agent Token",
|
|
2441
|
+
* symbol: "AGENT",
|
|
2442
|
+
* pairedToken: EXTERNAL.DIEM,
|
|
2443
|
+
* ...positions,
|
|
2444
|
+
* });
|
|
2445
|
+
* ```
|
|
2446
|
+
*/
|
|
2447
|
+
declare function createLiquidPositionsUSD(startingMarketCapUSD: number, pairedTokenPriceUSD: number, tickSpacing?: number): PositionArrays & {
|
|
2448
|
+
tickIfToken0IsLiquid: number;
|
|
2449
|
+
};
|
|
2383
2450
|
/**
|
|
2384
2451
|
* Describe positions as human-readable market cap ranges.
|
|
2385
2452
|
* Useful for displaying position info in UIs.
|
|
@@ -2496,7 +2563,7 @@ declare enum FeePreference {
|
|
|
2496
2563
|
*
|
|
2497
2564
|
* @example
|
|
2498
2565
|
* ```ts
|
|
2499
|
-
* // Single recipient, fees converted to
|
|
2566
|
+
* // Single recipient, fees converted to WETH
|
|
2500
2567
|
* const lockerData = encodeFeeConversionLockerData([FeePreference.Paired]);
|
|
2501
2568
|
*
|
|
2502
2569
|
* // Two recipients: first gets ETH, second gets the token
|
|
@@ -2557,4 +2624,4 @@ declare function parseContext(contextString: string): LiquidContext | null;
|
|
|
2557
2624
|
*/
|
|
2558
2625
|
declare function parseMetadata(metadataString: string): LiquidMetadata | null;
|
|
2559
2626
|
|
|
2560
|
-
export { ADDRESSES, type AirdropInfo, type BidInAuctionParams, type BidInAuctionResult, DEFAULTS, DEFAULT_CHAIN, DEFAULT_CHAIN_ID, DEFAULT_RPC_URL, DEFAULT_TRANCHES_USD, type DeployTokenParams, type DeployTokenResult, type DeploymentConfig, type DeploymentInfo, type DevBuyParams, type DynamicFeeConfig, ERC20Abi, EXTERNAL, type ExtensionConfig, FEE, FeePreference, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, LiquidMevDescendingFeesAbi, LiquidPoolExtensionAllowlistAbi, LiquidSDK, type LiquidSDKConfig, LiquidSniperAuctionV2Abi, LiquidSniperUtilV2Abi, LiquidTokenAbi, LiquidUniv4EthDevBuyAbi, LiquidVaultAbi, type LockerConfig, type MarketCapTranche, type MarketCapTrancheUSD, type MevModuleConfig, POOL_POSITIONS, type PoolConfig, type PoolDynamicConfigVars, type PoolDynamicFeeVars, type PoolKey, type PoolPosition, type PositionArrays, type PositionConfig, type SniperAuctionConfig, type SniperAuctionFeeConfig, type SniperAuctionState, type SocialMediaUrl, TOKEN, type TokenConfig, type TokenCreatedEvent, type TokenRewardInfo, type VaultAllocation, type VaultExtensionParams, buildContext, buildMetadata, createDefaultPositions, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeFeeConversionLockerData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata };
|
|
2627
|
+
export { ADDRESSES, type AirdropExtensionParams, type AirdropInfo, type BidInAuctionParams, type BidInAuctionResult, DEFAULTS, DEFAULT_CHAIN, DEFAULT_CHAIN_ID, DEFAULT_RPC_URL, DEFAULT_TRANCHES_USD, type DeployTokenParams, type DeployTokenResult, type DeploymentConfig, type DeploymentInfo, type DevBuyParams, type DynamicFeeConfig, ERC20Abi, EXTERNAL, type ExtensionConfig, FEE, FeePreference, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, LiquidMevDescendingFeesAbi, LiquidPoolExtensionAllowlistAbi, LiquidSDK, type LiquidSDKConfig, LiquidSniperAuctionV2Abi, LiquidSniperUtilV2Abi, LiquidTokenAbi, LiquidUniv4EthDevBuyAbi, LiquidVaultAbi, type LockerConfig, type MarketCapTranche, type MarketCapTrancheUSD, type MevModuleConfig, POOL_POSITIONS, type PoolConfig, type PoolDynamicConfigVars, type PoolDynamicFeeVars, type PoolKey, type PoolPosition, type PositionArrays, type PositionConfig, type SniperAuctionConfig, type SniperAuctionFeeConfig, type SniperAuctionState, type SocialMediaUrl, TOKEN, type TokenConfig, type TokenCreatedEvent, type TokenRewardInfo, type VaultAllocation, type VaultExtensionParams, buildContext, buildMetadata, createDefaultPositions, createLiquidPositionsUSD, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeFeeConversionLockerData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata, shiftPositions };
|
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,21 @@ interface VaultExtensionParams {
|
|
|
63
63
|
/** Vesting duration in seconds after lockup ends (0 = no vesting, tokens unlock all at once) */
|
|
64
64
|
vestingDuration?: number;
|
|
65
65
|
}
|
|
66
|
+
interface AirdropExtensionParams {
|
|
67
|
+
/** Address allowed to `updateAdmin`, `updateMerkleRoot` (under conditions),
|
|
68
|
+
* and `adminClaim` the remainder after claim expiration. */
|
|
69
|
+
admin: Address;
|
|
70
|
+
/** Merkle root over leaves `keccak256(bytes.concat(keccak256(abi.encode(
|
|
71
|
+
* recipient, allocatedAmount))))`. Double-hashed per OZ convention. */
|
|
72
|
+
merkleRoot: Hex;
|
|
73
|
+
/** Percentage of supply to reserve for the airdrop, in BPS (1–9000). */
|
|
74
|
+
allocationBps: number;
|
|
75
|
+
/** Lockup in seconds before any recipient can claim. Min 86400 (1 day). */
|
|
76
|
+
lockupDuration: number;
|
|
77
|
+
/** Linear vesting after lockup. 0 = instant claim of full entitlement at
|
|
78
|
+
* lockup end. */
|
|
79
|
+
vestingDuration?: number;
|
|
80
|
+
}
|
|
66
81
|
interface DeployTokenParams {
|
|
67
82
|
name: string;
|
|
68
83
|
symbol: string;
|
|
@@ -270,6 +285,29 @@ declare class LiquidSDK {
|
|
|
270
285
|
* ```
|
|
271
286
|
*/
|
|
272
287
|
buildVaultExtension(vault: VaultExtensionParams): ExtensionConfig;
|
|
288
|
+
/**
|
|
289
|
+
* Build an ExtensionConfig that reserves a percentage of supply into
|
|
290
|
+
* the LiquidAirdropV2 contract for merkle-tree-based distribution.
|
|
291
|
+
*
|
|
292
|
+
* The airdrop contract expects `AirdropV2ExtensionData`:
|
|
293
|
+
* { address admin, bytes32 merkleRoot, uint256 lockupDuration, uint256 vestingDuration }
|
|
294
|
+
*
|
|
295
|
+
* Leaf encoding used by LiquidAirdropV2.claim (note: **double hashed**
|
|
296
|
+
* — OZ's standard 2nd-preimage-resistant pattern):
|
|
297
|
+
* leaf = keccak256(bytes.concat(keccak256(abi.encode(recipient, allocatedAmount))))
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const airdropExt = sdk.buildAirdropExtension({
|
|
302
|
+
* admin: account.address,
|
|
303
|
+
* merkleRoot: "0x…",
|
|
304
|
+
* allocationBps: 2000, // 20%
|
|
305
|
+
* lockupDuration: 86400, // 1 day (minimum)
|
|
306
|
+
* vestingDuration: 0, // instant claim after lockup
|
|
307
|
+
* });
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
buildAirdropExtension(airdrop: AirdropExtensionParams): ExtensionConfig;
|
|
273
311
|
/**
|
|
274
312
|
* Validate a DeploymentConfig before sending to the contract.
|
|
275
313
|
* Catches common mistakes client-side with clear error messages.
|
|
@@ -433,6 +471,9 @@ declare const ADDRESSES: {
|
|
|
433
471
|
declare const EXTERNAL: {
|
|
434
472
|
readonly POOL_MANAGER: Address;
|
|
435
473
|
readonly WETH: Address;
|
|
474
|
+
/** DIEM — Liquid's intelligence-economy token. Also a pair token for
|
|
475
|
+
* agent-token launches (see `createLiquidPositionsUSD`). */
|
|
476
|
+
readonly DIEM: Address;
|
|
436
477
|
readonly UNIVERSAL_ROUTER: Address;
|
|
437
478
|
readonly PERMIT2: Address;
|
|
438
479
|
};
|
|
@@ -489,7 +530,7 @@ declare const POOL_POSITIONS: {
|
|
|
489
530
|
*/
|
|
490
531
|
declare const DEFAULTS: {
|
|
491
532
|
readonly HOOK: `0x${string}`;
|
|
492
|
-
/** LP Locker with fee conversion (converts fees to
|
|
533
|
+
/** LP Locker with fee conversion (converts fees to WETH before distributing) */
|
|
493
534
|
readonly LOCKER: `0x${string}`;
|
|
494
535
|
readonly TICK_SPACING: 200;
|
|
495
536
|
readonly TICK_IF_TOKEN0_IS_LIQUID: -230400;
|
|
@@ -583,31 +624,7 @@ declare const DEFAULT_CHAIN: {
|
|
|
583
624
|
formatters: {
|
|
584
625
|
readonly block: {
|
|
585
626
|
exclude: [] | undefined;
|
|
586
|
-
format: (args: viem_chains.OpStackRpcBlock, action
|
|
587
|
-
/**
|
|
588
|
-
* Pre-built position configurations.
|
|
589
|
-
*
|
|
590
|
-
* - **Standard**: Single position covering full range (~$20K → $1.5B).
|
|
591
|
-
* Default starting tick -230400 (≈10 ETH market cap).
|
|
592
|
-
*
|
|
593
|
-
* - **Liquid**: 3-tranche default for Liquid Protocol.
|
|
594
|
-
* Hardcoded for ≈10 ETH start at ~$2070/ETH.
|
|
595
|
-
* For dynamic market cap targets, use `createPositionsUSD()` instead.
|
|
596
|
-
*
|
|
597
|
-
* Note: positionBps must sum to 10,000 (100%).
|
|
598
|
-
*/
|
|
599
|
-
? /**
|
|
600
|
-
* Pre-built position configurations.
|
|
601
|
-
*
|
|
602
|
-
* - **Standard**: Single position covering full range (~$20K → $1.5B).
|
|
603
|
-
* Default starting tick -230400 (≈10 ETH market cap).
|
|
604
|
-
*
|
|
605
|
-
* - **Liquid**: 3-tranche default for Liquid Protocol.
|
|
606
|
-
* Hardcoded for ≈10 ETH start at ~$2070/ETH.
|
|
607
|
-
* For dynamic market cap targets, use `createPositionsUSD()` instead.
|
|
608
|
-
*
|
|
609
|
-
* Note: positionBps must sum to 10,000 (100%).
|
|
610
|
-
*/: string | undefined) => {
|
|
627
|
+
format: (args: viem_chains.OpStackRpcBlock, action?: string | undefined) => {
|
|
611
628
|
baseFeePerGas: bigint | null;
|
|
612
629
|
blobGasUsed: bigint;
|
|
613
630
|
difficulty: bigint;
|
|
@@ -2285,6 +2302,7 @@ declare function getTickFromMarketCapStable(marketCap: number, stableDecimals: n
|
|
|
2285
2302
|
* market cap milestones. Percentages represent share of the *pool supply*
|
|
2286
2303
|
* (i.e. after dev buy, airdrop, and vault allocations are deducted).
|
|
2287
2304
|
*/
|
|
2305
|
+
|
|
2288
2306
|
interface MarketCapTranche {
|
|
2289
2307
|
/** Upper bound market cap in ETH for this tranche */
|
|
2290
2308
|
upperMarketCapETH: number;
|
|
@@ -2380,6 +2398,55 @@ declare function createPositionsUSD(startingMarketCapUSD: number, ethPriceUSD: n
|
|
|
2380
2398
|
declare function createDefaultPositions(startingMarketCapUSD: number, ethPriceUSD: number, tickSpacing?: number): PositionArrays & {
|
|
2381
2399
|
tickIfToken0IsLiquid: number;
|
|
2382
2400
|
};
|
|
2401
|
+
/**
|
|
2402
|
+
* Shift every tick in a position layout by a fixed amount, preserving the
|
|
2403
|
+
* positionBps splits. The primitive behind `createLiquidPositionsUSD` — it
|
|
2404
|
+
* re-anchors a fixed-shape layout (e.g. `POOL_POSITIONS.Liquid`) to a
|
|
2405
|
+
* different starting tick.
|
|
2406
|
+
*
|
|
2407
|
+
* `shiftBy` should be a multiple of the pool's tick spacing so the shifted
|
|
2408
|
+
* ticks stay aligned. A difference of two aligned ticks is always aligned,
|
|
2409
|
+
* so deriving it as `targetTick - sourceBottomTick` is safe.
|
|
2410
|
+
*
|
|
2411
|
+
* @param positions - Source positions (e.g. `POOL_POSITIONS.Liquid`)
|
|
2412
|
+
* @param shiftBy - Ticks to add to every tickLower/tickUpper (may be negative)
|
|
2413
|
+
* @returns A fresh array — the source is not mutated
|
|
2414
|
+
*/
|
|
2415
|
+
declare function shiftPositions(positions: readonly PoolPosition[], shiftBy: number): PoolPosition[];
|
|
2416
|
+
/**
|
|
2417
|
+
* Build the canonical 5-position "Liquid" layout (10/50/15/20/5) re-anchored
|
|
2418
|
+
* to a starting market cap, denominated in the *paired token's* USD price.
|
|
2419
|
+
*
|
|
2420
|
+
* Works for any pair token — pass the price of whatever the pool is paired
|
|
2421
|
+
* against:
|
|
2422
|
+
* - WETH-paired: `createLiquidPositionsUSD(20_000, ethPriceUSD)`
|
|
2423
|
+
* - DIEM-paired: `createLiquidPositionsUSD(20_000, diemPriceUSD)`
|
|
2424
|
+
*
|
|
2425
|
+
* Unlike `createDefaultPositions` (a 3-tranche layout), this preserves the
|
|
2426
|
+
* exact shape of `POOL_POSITIONS.Liquid` — the same curve `deployToken()`
|
|
2427
|
+
* uses by default — just shifted so its bottom sits at the requested start.
|
|
2428
|
+
*
|
|
2429
|
+
* @param startingMarketCapUSD - Initial market cap in USD
|
|
2430
|
+
* @param pairedTokenPriceUSD - USD price of the token the pool is paired against
|
|
2431
|
+
* @param tickSpacing - Tick spacing (default 200)
|
|
2432
|
+
* @returns Position arrays + `tickIfToken0IsLiquid`, ready to spread into `deployToken()`
|
|
2433
|
+
*
|
|
2434
|
+
* @example
|
|
2435
|
+
* ```ts
|
|
2436
|
+
* import { LiquidSDK, EXTERNAL, createLiquidPositionsUSD } from "liquid-sdk";
|
|
2437
|
+
*
|
|
2438
|
+
* const positions = createLiquidPositionsUSD(20_000, diemPriceUSD);
|
|
2439
|
+
* await sdk.deployToken({
|
|
2440
|
+
* name: "Agent Token",
|
|
2441
|
+
* symbol: "AGENT",
|
|
2442
|
+
* pairedToken: EXTERNAL.DIEM,
|
|
2443
|
+
* ...positions,
|
|
2444
|
+
* });
|
|
2445
|
+
* ```
|
|
2446
|
+
*/
|
|
2447
|
+
declare function createLiquidPositionsUSD(startingMarketCapUSD: number, pairedTokenPriceUSD: number, tickSpacing?: number): PositionArrays & {
|
|
2448
|
+
tickIfToken0IsLiquid: number;
|
|
2449
|
+
};
|
|
2383
2450
|
/**
|
|
2384
2451
|
* Describe positions as human-readable market cap ranges.
|
|
2385
2452
|
* Useful for displaying position info in UIs.
|
|
@@ -2496,7 +2563,7 @@ declare enum FeePreference {
|
|
|
2496
2563
|
*
|
|
2497
2564
|
* @example
|
|
2498
2565
|
* ```ts
|
|
2499
|
-
* // Single recipient, fees converted to
|
|
2566
|
+
* // Single recipient, fees converted to WETH
|
|
2500
2567
|
* const lockerData = encodeFeeConversionLockerData([FeePreference.Paired]);
|
|
2501
2568
|
*
|
|
2502
2569
|
* // Two recipients: first gets ETH, second gets the token
|
|
@@ -2557,4 +2624,4 @@ declare function parseContext(contextString: string): LiquidContext | null;
|
|
|
2557
2624
|
*/
|
|
2558
2625
|
declare function parseMetadata(metadataString: string): LiquidMetadata | null;
|
|
2559
2626
|
|
|
2560
|
-
export { ADDRESSES, type AirdropInfo, type BidInAuctionParams, type BidInAuctionResult, DEFAULTS, DEFAULT_CHAIN, DEFAULT_CHAIN_ID, DEFAULT_RPC_URL, DEFAULT_TRANCHES_USD, type DeployTokenParams, type DeployTokenResult, type DeploymentConfig, type DeploymentInfo, type DevBuyParams, type DynamicFeeConfig, ERC20Abi, EXTERNAL, type ExtensionConfig, FEE, FeePreference, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, LiquidMevDescendingFeesAbi, LiquidPoolExtensionAllowlistAbi, LiquidSDK, type LiquidSDKConfig, LiquidSniperAuctionV2Abi, LiquidSniperUtilV2Abi, LiquidTokenAbi, LiquidUniv4EthDevBuyAbi, LiquidVaultAbi, type LockerConfig, type MarketCapTranche, type MarketCapTrancheUSD, type MevModuleConfig, POOL_POSITIONS, type PoolConfig, type PoolDynamicConfigVars, type PoolDynamicFeeVars, type PoolKey, type PoolPosition, type PositionArrays, type PositionConfig, type SniperAuctionConfig, type SniperAuctionFeeConfig, type SniperAuctionState, type SocialMediaUrl, TOKEN, type TokenConfig, type TokenCreatedEvent, type TokenRewardInfo, type VaultAllocation, type VaultExtensionParams, buildContext, buildMetadata, createDefaultPositions, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeFeeConversionLockerData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata };
|
|
2627
|
+
export { ADDRESSES, type AirdropExtensionParams, type AirdropInfo, type BidInAuctionParams, type BidInAuctionResult, DEFAULTS, DEFAULT_CHAIN, DEFAULT_CHAIN_ID, DEFAULT_RPC_URL, DEFAULT_TRANCHES_USD, type DeployTokenParams, type DeployTokenResult, type DeploymentConfig, type DeploymentInfo, type DevBuyParams, type DynamicFeeConfig, ERC20Abi, EXTERNAL, type ExtensionConfig, FEE, FeePreference, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, LiquidMevDescendingFeesAbi, LiquidPoolExtensionAllowlistAbi, LiquidSDK, type LiquidSDKConfig, LiquidSniperAuctionV2Abi, LiquidSniperUtilV2Abi, LiquidTokenAbi, LiquidUniv4EthDevBuyAbi, LiquidVaultAbi, type LockerConfig, type MarketCapTranche, type MarketCapTrancheUSD, type MevModuleConfig, POOL_POSITIONS, type PoolConfig, type PoolDynamicConfigVars, type PoolDynamicFeeVars, type PoolKey, type PoolPosition, type PositionArrays, type PositionConfig, type SniperAuctionConfig, type SniperAuctionFeeConfig, type SniperAuctionState, type SocialMediaUrl, TOKEN, type TokenConfig, type TokenCreatedEvent, type TokenRewardInfo, type VaultAllocation, type VaultExtensionParams, buildContext, buildMetadata, createDefaultPositions, createLiquidPositionsUSD, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeFeeConversionLockerData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata, shiftPositions };
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ __export(index_exports, {
|
|
|
49
49
|
buildContext: () => buildContext,
|
|
50
50
|
buildMetadata: () => buildMetadata,
|
|
51
51
|
createDefaultPositions: () => createDefaultPositions,
|
|
52
|
+
createLiquidPositionsUSD: () => createLiquidPositionsUSD,
|
|
52
53
|
createPositions: () => createPositions,
|
|
53
54
|
createPositionsUSD: () => createPositionsUSD,
|
|
54
55
|
describePositions: () => describePositions,
|
|
@@ -62,7 +63,8 @@ __export(index_exports, {
|
|
|
62
63
|
marketCapFromTickETH: () => marketCapFromTickETH,
|
|
63
64
|
marketCapFromTickUSD: () => marketCapFromTickUSD,
|
|
64
65
|
parseContext: () => parseContext,
|
|
65
|
-
parseMetadata: () => parseMetadata
|
|
66
|
+
parseMetadata: () => parseMetadata,
|
|
67
|
+
shiftPositions: () => shiftPositions
|
|
66
68
|
});
|
|
67
69
|
module.exports = __toCommonJS(index_exports);
|
|
68
70
|
|
|
@@ -92,6 +94,9 @@ var ADDRESSES = {
|
|
|
92
94
|
var EXTERNAL = {
|
|
93
95
|
POOL_MANAGER: "0x498581fF718922c3f8e6A244956aF099B2652b2b",
|
|
94
96
|
WETH: "0x4200000000000000000000000000000000000006",
|
|
97
|
+
/** DIEM — Liquid's intelligence-economy token. Also a pair token for
|
|
98
|
+
* agent-token launches (see `createLiquidPositionsUSD`). */
|
|
99
|
+
DIEM: "0xF4d97F2da56e8c3098f3a8D538DB630A2606a024",
|
|
95
100
|
UNIVERSAL_ROUTER: "0x6fF5693b99212Da76ad316178A184AB56D299b43",
|
|
96
101
|
PERMIT2: "0x000000000022D473030F116dDEE9F6B43aC78BA3"
|
|
97
102
|
};
|
|
@@ -161,7 +166,7 @@ var POOL_POSITIONS = {
|
|
|
161
166
|
};
|
|
162
167
|
var DEFAULTS = {
|
|
163
168
|
HOOK: ADDRESSES.HOOK_STATIC_FEE_V2,
|
|
164
|
-
/** LP Locker with fee conversion (converts fees to
|
|
169
|
+
/** LP Locker with fee conversion (converts fees to WETH before distributing) */
|
|
165
170
|
LOCKER: ADDRESSES.LP_LOCKER_FEE_CONVERSION,
|
|
166
171
|
TICK_SPACING: 200,
|
|
167
172
|
TICK_IF_TOKEN0_IS_LIQUID: -230400,
|
|
@@ -1201,6 +1206,73 @@ var LiquidSDK = class {
|
|
|
1201
1206
|
extensionData
|
|
1202
1207
|
};
|
|
1203
1208
|
}
|
|
1209
|
+
// ── Airdrop Extension ──────────────────────────────────────────
|
|
1210
|
+
/**
|
|
1211
|
+
* Build an ExtensionConfig that reserves a percentage of supply into
|
|
1212
|
+
* the LiquidAirdropV2 contract for merkle-tree-based distribution.
|
|
1213
|
+
*
|
|
1214
|
+
* The airdrop contract expects `AirdropV2ExtensionData`:
|
|
1215
|
+
* { address admin, bytes32 merkleRoot, uint256 lockupDuration, uint256 vestingDuration }
|
|
1216
|
+
*
|
|
1217
|
+
* Leaf encoding used by LiquidAirdropV2.claim (note: **double hashed**
|
|
1218
|
+
* — OZ's standard 2nd-preimage-resistant pattern):
|
|
1219
|
+
* leaf = keccak256(bytes.concat(keccak256(abi.encode(recipient, allocatedAmount))))
|
|
1220
|
+
*
|
|
1221
|
+
* @example
|
|
1222
|
+
* ```typescript
|
|
1223
|
+
* const airdropExt = sdk.buildAirdropExtension({
|
|
1224
|
+
* admin: account.address,
|
|
1225
|
+
* merkleRoot: "0x…",
|
|
1226
|
+
* allocationBps: 2000, // 20%
|
|
1227
|
+
* lockupDuration: 86400, // 1 day (minimum)
|
|
1228
|
+
* vestingDuration: 0, // instant claim after lockup
|
|
1229
|
+
* });
|
|
1230
|
+
* ```
|
|
1231
|
+
*/
|
|
1232
|
+
buildAirdropExtension(airdrop) {
|
|
1233
|
+
const MIN_LOCKUP = 86400;
|
|
1234
|
+
const MAX_BPS = 9e3;
|
|
1235
|
+
if (airdrop.allocationBps < 1 || airdrop.allocationBps > MAX_BPS) {
|
|
1236
|
+
throw new Error(
|
|
1237
|
+
`Airdrop allocationBps must be 1\u2013${MAX_BPS} (0.01%\u201390%). Got ${airdrop.allocationBps}.`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
if (airdrop.lockupDuration < MIN_LOCKUP) {
|
|
1241
|
+
throw new Error(
|
|
1242
|
+
`Airdrop lockupDuration must be \u2265 ${MIN_LOCKUP} seconds (1 day). Got ${airdrop.lockupDuration}.`
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
if (airdrop.vestingDuration !== void 0 && airdrop.vestingDuration < 0) {
|
|
1246
|
+
throw new Error("Airdrop vestingDuration cannot be negative.");
|
|
1247
|
+
}
|
|
1248
|
+
const extensionData = (0, import_viem2.encodeAbiParameters)(
|
|
1249
|
+
[
|
|
1250
|
+
{
|
|
1251
|
+
type: "tuple",
|
|
1252
|
+
components: [
|
|
1253
|
+
{ type: "address", name: "admin" },
|
|
1254
|
+
{ type: "bytes32", name: "merkleRoot" },
|
|
1255
|
+
{ type: "uint256", name: "lockupDuration" },
|
|
1256
|
+
{ type: "uint256", name: "vestingDuration" }
|
|
1257
|
+
]
|
|
1258
|
+
}
|
|
1259
|
+
],
|
|
1260
|
+
[
|
|
1261
|
+
{
|
|
1262
|
+
admin: airdrop.admin,
|
|
1263
|
+
merkleRoot: airdrop.merkleRoot,
|
|
1264
|
+
lockupDuration: BigInt(airdrop.lockupDuration),
|
|
1265
|
+
vestingDuration: BigInt(airdrop.vestingDuration ?? 0)
|
|
1266
|
+
}
|
|
1267
|
+
]
|
|
1268
|
+
);
|
|
1269
|
+
return {
|
|
1270
|
+
extension: ADDRESSES.AIRDROP_V2,
|
|
1271
|
+
msgValue: 0n,
|
|
1272
|
+
extensionBps: airdrop.allocationBps,
|
|
1273
|
+
extensionData
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1204
1276
|
// ── Validation ─────────────────────────────────────────────────
|
|
1205
1277
|
/**
|
|
1206
1278
|
* Validate a DeploymentConfig before sending to the contract.
|
|
@@ -1365,13 +1437,36 @@ var LiquidSDK = class {
|
|
|
1365
1437
|
(sum, ext) => sum + ext.msgValue,
|
|
1366
1438
|
0n
|
|
1367
1439
|
);
|
|
1440
|
+
let gas;
|
|
1441
|
+
try {
|
|
1442
|
+
const estimated = await this.publicClient.estimateContractGas({
|
|
1443
|
+
address: ADDRESSES.FACTORY,
|
|
1444
|
+
abi: LiquidFactoryAbi,
|
|
1445
|
+
functionName: "deployToken",
|
|
1446
|
+
args: [deploymentConfig],
|
|
1447
|
+
value: msgValue,
|
|
1448
|
+
account: this.walletClient.account
|
|
1449
|
+
});
|
|
1450
|
+
gas = estimated * 120n / 100n;
|
|
1451
|
+
} catch (err) {
|
|
1452
|
+
const e = err;
|
|
1453
|
+
const looksLikeRevert = e?.name === "ContractFunctionExecutionError" || e?.name === "CallExecutionError" || typeof e?.shortMessage === "string" && /reverted|revert reason|execution reverted/i.test(e.shortMessage);
|
|
1454
|
+
if (looksLikeRevert) throw err;
|
|
1455
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
1456
|
+
console.warn(
|
|
1457
|
+
"[liquid-sdk] deployToken gas estimation failed; falling back to 6M gas limit:",
|
|
1458
|
+
e?.shortMessage ?? err
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1461
|
+
gas = 6000000n;
|
|
1462
|
+
}
|
|
1368
1463
|
const txHash = await this.walletClient.writeContract({
|
|
1369
1464
|
address: ADDRESSES.FACTORY,
|
|
1370
1465
|
abi: LiquidFactoryAbi,
|
|
1371
1466
|
functionName: "deployToken",
|
|
1372
1467
|
args: [deploymentConfig],
|
|
1373
1468
|
value: msgValue,
|
|
1374
|
-
gas
|
|
1469
|
+
gas,
|
|
1375
1470
|
chain: import_chains2.base,
|
|
1376
1471
|
account: this.walletClient.account
|
|
1377
1472
|
});
|
|
@@ -2356,6 +2451,33 @@ function createDefaultPositions(startingMarketCapUSD, ethPriceUSD, tickSpacing =
|
|
|
2356
2451
|
tickIfToken0IsLiquid: positions.tickLower[0]
|
|
2357
2452
|
};
|
|
2358
2453
|
}
|
|
2454
|
+
function shiftPositions(positions, shiftBy) {
|
|
2455
|
+
return positions.map((p) => ({
|
|
2456
|
+
tickLower: p.tickLower + shiftBy,
|
|
2457
|
+
tickUpper: p.tickUpper + shiftBy,
|
|
2458
|
+
positionBps: p.positionBps
|
|
2459
|
+
}));
|
|
2460
|
+
}
|
|
2461
|
+
function createLiquidPositionsUSD(startingMarketCapUSD, pairedTokenPriceUSD, tickSpacing = 200) {
|
|
2462
|
+
if (pairedTokenPriceUSD <= 0) {
|
|
2463
|
+
throw new Error("pairedTokenPriceUSD must be positive");
|
|
2464
|
+
}
|
|
2465
|
+
const startingTick = getTickFromMarketCapUSD(
|
|
2466
|
+
startingMarketCapUSD,
|
|
2467
|
+
pairedTokenPriceUSD,
|
|
2468
|
+
tickSpacing
|
|
2469
|
+
);
|
|
2470
|
+
const shifted = shiftPositions(
|
|
2471
|
+
POOL_POSITIONS.Liquid,
|
|
2472
|
+
startingTick - DEFAULTS.TICK_IF_TOKEN0_IS_LIQUID
|
|
2473
|
+
);
|
|
2474
|
+
return {
|
|
2475
|
+
tickLower: shifted.map((p) => p.tickLower),
|
|
2476
|
+
tickUpper: shifted.map((p) => p.tickUpper),
|
|
2477
|
+
positionBps: shifted.map((p) => p.positionBps),
|
|
2478
|
+
tickIfToken0IsLiquid: startingTick
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2359
2481
|
function describePositions(positions, ethPriceUSD) {
|
|
2360
2482
|
return positions.tickLower.map((_, i) => {
|
|
2361
2483
|
const lowerETH = Math.pow(1.0001, positions.tickLower[i]) * 1e11;
|
|
@@ -2405,6 +2527,7 @@ function describePositions(positions, ethPriceUSD) {
|
|
|
2405
2527
|
buildContext,
|
|
2406
2528
|
buildMetadata,
|
|
2407
2529
|
createDefaultPositions,
|
|
2530
|
+
createLiquidPositionsUSD,
|
|
2408
2531
|
createPositions,
|
|
2409
2532
|
createPositionsUSD,
|
|
2410
2533
|
describePositions,
|
|
@@ -2418,6 +2541,7 @@ function describePositions(positions, ethPriceUSD) {
|
|
|
2418
2541
|
marketCapFromTickETH,
|
|
2419
2542
|
marketCapFromTickUSD,
|
|
2420
2543
|
parseContext,
|
|
2421
|
-
parseMetadata
|
|
2544
|
+
parseMetadata,
|
|
2545
|
+
shiftPositions
|
|
2422
2546
|
});
|
|
2423
2547
|
//# sourceMappingURL=index.js.map
|