liquid-sdk 1.2.0 → 1.3.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/AGENT_README.md +770 -0
- package/CHANGELOG.md +60 -0
- package/dist/index.d.mts +95 -1
- package/dist/index.d.ts +95 -1
- package/dist/index.js +149 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +144 -10
- package/dist/index.mjs.map +1 -1
- package/llms.txt +154 -0
- package/package.json +22 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `liquid-sdk` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.2.0] - 2025-03-10
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `getDeployedTokens(deployer, fromBlock?, toBlock?)` — query all tokens deployed by an address via on-chain events
|
|
9
|
+
- `buildContext()` / `buildMetadata()` helpers for structured on-chain context and metadata
|
|
10
|
+
- `parseContext()` / `parseMetadata()` for reading context/metadata back from on-chain strings
|
|
11
|
+
- `LiquidContext` and `LiquidMetadata` type exports
|
|
12
|
+
- Auto-default `context` field to `{"interface":"SDK"}` when no context is provided to `deployToken()`
|
|
13
|
+
- `AGENT_README.md` — 700+ line reference optimized for AI agents and LLM-assisted development
|
|
14
|
+
- `llms.txt` — structured summary following the llms-txt.org specification
|
|
15
|
+
- `.cursor/skills/use-liquid-sdk/SKILL.md` — Cursor IDE auto-discovery skill
|
|
16
|
+
- 8 runnable examples in `examples/` directory
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Expanded NPM keywords for better discoverability (erc20, deploy, defi, web3, etc.)
|
|
20
|
+
- Updated package description to highlight zero-API-key, single-dependency value prop
|
|
21
|
+
- `files` array now includes README.md, AGENT_README.md, CHANGELOG.md, and llms.txt
|
|
22
|
+
|
|
23
|
+
## [1.1.0] - 2025-02-28
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Custom position builders: `createPositions()`, `createPositionsUSD()`, `createDefaultPositions()`
|
|
27
|
+
- `describePositions()` for human-readable market cap range descriptions
|
|
28
|
+
- Tick ↔ market cap conversion utilities: `getTickFromMarketCapETH`, `getTickFromMarketCapUSD`, `marketCapFromTickETH`, `marketCapFromTickUSD`
|
|
29
|
+
- Dynamic fee pool data encoding: `encodeDynamicFeePoolData()`
|
|
30
|
+
- Sniper auction data encoding: `encodeSniperAuctionData()`
|
|
31
|
+
- `DEFAULT_TRANCHES_USD` preset (40% @ $500K, 50% @ $10M, 10% @ $1B)
|
|
32
|
+
- Pool reads: `getPoolConfig()`, `getPoolFeeState()`, `getPoolCreationTimestamp()`, `isLiquidToken0()`
|
|
33
|
+
- Sniper auction reads: `getAuctionState()`, `getAuctionFeeConfig()`, `getAuctionDecayStartTime()`, `getAuctionMaxRounds()`, `getAuctionGasPriceForBid()`
|
|
34
|
+
- MEV protection reads: `getMevBlockDelay()`, `getPoolUnlockTime()`
|
|
35
|
+
- Comprehensive client-side validation in `deployToken()` with clear error messages
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- Default hook switched to `HOOK_STATIC_FEE_V2` with proper two-layer pool data encoding
|
|
39
|
+
- Default positions changed from single full-range to 3-tranche Liquid preset
|
|
40
|
+
- Default MEV module switched to `SNIPER_AUCTION_V2` with 80%→40% decay over 32s
|
|
41
|
+
|
|
42
|
+
## [1.0.0] - 2025-02-15
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- Initial release of `liquid-sdk`
|
|
46
|
+
- `LiquidSDK` class with full token lifecycle support
|
|
47
|
+
- `deployToken()` — deploy ERC-20 tokens with Uniswap V4 liquidity on Base
|
|
48
|
+
- Dev buy support — buy tokens with ETH in the same deployment transaction
|
|
49
|
+
- Fee management: `getAvailableFees()`, `getFeesToClaim()`, `claimFees()`
|
|
50
|
+
- LP reward management: `getTokenRewards()`, `collectRewards()`, `collectRewardsWithoutUnlock()`, `updateRewardRecipient()`
|
|
51
|
+
- Vault management: `getVaultAllocation()`, `getVaultClaimable()`, `claimVault()`
|
|
52
|
+
- Airdrop support: `getAirdropInfo()`, `getAirdropClaimable()`, `claimAirdrop()`
|
|
53
|
+
- Token info: `getTokenInfo()`, `getDeploymentInfo()`
|
|
54
|
+
- Token metadata updates: `updateImage()`, `updateMetadata()`
|
|
55
|
+
- Factory status checks: `isFactoryDeprecated()`, `isLockerEnabled()`, `isExtensionEnabled()`
|
|
56
|
+
- Static fee pool data encoding: `encodeStaticFeePoolData()`
|
|
57
|
+
- All 13 contract ABIs exported
|
|
58
|
+
- All type definitions exported
|
|
59
|
+
- Dual build output: CJS + ESM with TypeScript declarations
|
|
60
|
+
- Single peer dependency: `viem ^2.0.0`
|
package/dist/index.d.mts
CHANGED
|
@@ -151,6 +151,17 @@ interface TokenCreatedEvent {
|
|
|
151
151
|
mevModule: Address;
|
|
152
152
|
extensionsSupply: bigint;
|
|
153
153
|
extensions: Address[];
|
|
154
|
+
/** Block number where the token was created (populated by discovery methods) */
|
|
155
|
+
blockNumber?: bigint;
|
|
156
|
+
}
|
|
157
|
+
/** Options for querying deployed tokens. */
|
|
158
|
+
interface GetTokensOptions {
|
|
159
|
+
/** Filter by deployer address (msgSender). If omitted, returns all tokens. */
|
|
160
|
+
deployer?: Address;
|
|
161
|
+
/** Starting block to search from (defaults to factory deployment block) */
|
|
162
|
+
fromBlock?: bigint;
|
|
163
|
+
/** Ending block to search to (defaults to 'latest') */
|
|
164
|
+
toBlock?: bigint | "latest";
|
|
154
165
|
}
|
|
155
166
|
interface AirdropInfo {
|
|
156
167
|
admin: Address;
|
|
@@ -258,6 +269,35 @@ declare class LiquidSDK {
|
|
|
258
269
|
* @param toBlock - Ending block to search to (defaults to 'latest')
|
|
259
270
|
*/
|
|
260
271
|
getDeployedTokens(deployer: Address, fromBlock?: bigint, toBlock?: bigint | "latest"): Promise<TokenCreatedEvent[]>;
|
|
272
|
+
/**
|
|
273
|
+
* Query TokenCreated events with optional filtering.
|
|
274
|
+
*
|
|
275
|
+
* Use this for token discovery, indexing, or building token lists.
|
|
276
|
+
* Returns events in chronological order with block numbers for pagination.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* // Get all tokens
|
|
280
|
+
* const allTokens = await sdk.getTokens();
|
|
281
|
+
*
|
|
282
|
+
* // Get tokens by deployer
|
|
283
|
+
* const myTokens = await sdk.getTokens({ deployer: myAddress });
|
|
284
|
+
*
|
|
285
|
+
* // Paginate with block ranges
|
|
286
|
+
* const page1 = await sdk.getTokens({ fromBlock: 20000000n, toBlock: 20100000n });
|
|
287
|
+
* const page2 = await sdk.getTokens({ fromBlock: 20100001n, toBlock: 20200000n });
|
|
288
|
+
*/
|
|
289
|
+
getTokens(options?: GetTokensOptions): Promise<TokenCreatedEvent[]>;
|
|
290
|
+
/**
|
|
291
|
+
* Look up a single token's on-chain event data by contract address.
|
|
292
|
+
*
|
|
293
|
+
* Returns the full TokenCreated event including metadata, context, poolId,
|
|
294
|
+
* hook, locker, extensions — everything a wallet or aggregator needs to
|
|
295
|
+
* display the token. Returns `null` if not found.
|
|
296
|
+
*
|
|
297
|
+
* This is indexed on-chain (tokenAddress is indexed in the event), so it's
|
|
298
|
+
* a single RPC call regardless of how many tokens exist.
|
|
299
|
+
*/
|
|
300
|
+
getTokenEvent(tokenAddress: Address): Promise<TokenCreatedEvent | null>;
|
|
261
301
|
}
|
|
262
302
|
|
|
263
303
|
declare const ADDRESSES: {
|
|
@@ -335,6 +375,8 @@ declare const POOL_POSITIONS: {
|
|
|
335
375
|
*/
|
|
336
376
|
declare const DEFAULTS: {
|
|
337
377
|
readonly HOOK: `0x${string}`;
|
|
378
|
+
/** LP Locker with fee conversion (converts fees to ETH before distributing) */
|
|
379
|
+
readonly LOCKER: `0x${string}`;
|
|
338
380
|
readonly TICK_SPACING: 200;
|
|
339
381
|
readonly TICK_IF_TOKEN0_IS_LIQUID: -230400;
|
|
340
382
|
/** Static fee on buys (ETH → token): 1% (100 bps). Fees collected in ETH. */
|
|
@@ -2270,4 +2312,56 @@ interface SniperAuctionConfig {
|
|
|
2270
2312
|
*/
|
|
2271
2313
|
declare function encodeSniperAuctionData(config: SniperAuctionConfig): Hex;
|
|
2272
2314
|
|
|
2273
|
-
|
|
2315
|
+
/** Provenance — who launched the token and from where. */
|
|
2316
|
+
interface LiquidContext {
|
|
2317
|
+
/** System that deployed the token (e.g. "SDK", "Rainbow Wallet", "Liquid CLI") */
|
|
2318
|
+
interface: string;
|
|
2319
|
+
/** Social platform origin (e.g. "Farcaster", "Twitter") */
|
|
2320
|
+
platform?: string;
|
|
2321
|
+
/** Social post/message ID that triggered the deploy */
|
|
2322
|
+
messageId?: string;
|
|
2323
|
+
/** User ID on the originating platform */
|
|
2324
|
+
id?: string;
|
|
2325
|
+
}
|
|
2326
|
+
/** Social media link for token metadata. */
|
|
2327
|
+
interface SocialMediaUrl {
|
|
2328
|
+
platform: string;
|
|
2329
|
+
url: string;
|
|
2330
|
+
}
|
|
2331
|
+
/** Token info for aggregators and explorers. */
|
|
2332
|
+
interface LiquidMetadata {
|
|
2333
|
+
/** Token/project description */
|
|
2334
|
+
description?: string;
|
|
2335
|
+
/** Social media links */
|
|
2336
|
+
socialMediaUrls?: SocialMediaUrl[];
|
|
2337
|
+
/** Audit report URLs */
|
|
2338
|
+
auditUrls?: string[];
|
|
2339
|
+
}
|
|
2340
|
+
/**
|
|
2341
|
+
* Build a JSON string for the on-chain `context` field.
|
|
2342
|
+
*
|
|
2343
|
+
* @example
|
|
2344
|
+
* buildContext({ interface: "My App", platform: "Farcaster" })
|
|
2345
|
+
* // '{"interface":"My App","platform":"Farcaster"}'
|
|
2346
|
+
*/
|
|
2347
|
+
declare function buildContext(input?: Partial<LiquidContext>): string;
|
|
2348
|
+
/**
|
|
2349
|
+
* Build a JSON string for the on-chain `metadata` field.
|
|
2350
|
+
*
|
|
2351
|
+
* @example
|
|
2352
|
+
* buildMetadata({ description: "A cool token" })
|
|
2353
|
+
* // '{"description":"A cool token"}'
|
|
2354
|
+
*/
|
|
2355
|
+
declare function buildMetadata(input?: Partial<LiquidMetadata>): string;
|
|
2356
|
+
/**
|
|
2357
|
+
* Parse a context JSON string back into a typed object.
|
|
2358
|
+
* Returns `null` if the string is empty or not valid JSON.
|
|
2359
|
+
*/
|
|
2360
|
+
declare function parseContext(contextString: string): LiquidContext | null;
|
|
2361
|
+
/**
|
|
2362
|
+
* Parse a metadata JSON string back into a typed object.
|
|
2363
|
+
* Returns `null` if the string is empty or not valid JSON.
|
|
2364
|
+
*/
|
|
2365
|
+
declare function parseMetadata(metadataString: string): LiquidMetadata | null;
|
|
2366
|
+
|
|
2367
|
+
export { ADDRESSES, type AirdropInfo, 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, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, 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, buildContext, buildMetadata, createDefaultPositions, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata };
|
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,17 @@ interface TokenCreatedEvent {
|
|
|
151
151
|
mevModule: Address;
|
|
152
152
|
extensionsSupply: bigint;
|
|
153
153
|
extensions: Address[];
|
|
154
|
+
/** Block number where the token was created (populated by discovery methods) */
|
|
155
|
+
blockNumber?: bigint;
|
|
156
|
+
}
|
|
157
|
+
/** Options for querying deployed tokens. */
|
|
158
|
+
interface GetTokensOptions {
|
|
159
|
+
/** Filter by deployer address (msgSender). If omitted, returns all tokens. */
|
|
160
|
+
deployer?: Address;
|
|
161
|
+
/** Starting block to search from (defaults to factory deployment block) */
|
|
162
|
+
fromBlock?: bigint;
|
|
163
|
+
/** Ending block to search to (defaults to 'latest') */
|
|
164
|
+
toBlock?: bigint | "latest";
|
|
154
165
|
}
|
|
155
166
|
interface AirdropInfo {
|
|
156
167
|
admin: Address;
|
|
@@ -258,6 +269,35 @@ declare class LiquidSDK {
|
|
|
258
269
|
* @param toBlock - Ending block to search to (defaults to 'latest')
|
|
259
270
|
*/
|
|
260
271
|
getDeployedTokens(deployer: Address, fromBlock?: bigint, toBlock?: bigint | "latest"): Promise<TokenCreatedEvent[]>;
|
|
272
|
+
/**
|
|
273
|
+
* Query TokenCreated events with optional filtering.
|
|
274
|
+
*
|
|
275
|
+
* Use this for token discovery, indexing, or building token lists.
|
|
276
|
+
* Returns events in chronological order with block numbers for pagination.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* // Get all tokens
|
|
280
|
+
* const allTokens = await sdk.getTokens();
|
|
281
|
+
*
|
|
282
|
+
* // Get tokens by deployer
|
|
283
|
+
* const myTokens = await sdk.getTokens({ deployer: myAddress });
|
|
284
|
+
*
|
|
285
|
+
* // Paginate with block ranges
|
|
286
|
+
* const page1 = await sdk.getTokens({ fromBlock: 20000000n, toBlock: 20100000n });
|
|
287
|
+
* const page2 = await sdk.getTokens({ fromBlock: 20100001n, toBlock: 20200000n });
|
|
288
|
+
*/
|
|
289
|
+
getTokens(options?: GetTokensOptions): Promise<TokenCreatedEvent[]>;
|
|
290
|
+
/**
|
|
291
|
+
* Look up a single token's on-chain event data by contract address.
|
|
292
|
+
*
|
|
293
|
+
* Returns the full TokenCreated event including metadata, context, poolId,
|
|
294
|
+
* hook, locker, extensions — everything a wallet or aggregator needs to
|
|
295
|
+
* display the token. Returns `null` if not found.
|
|
296
|
+
*
|
|
297
|
+
* This is indexed on-chain (tokenAddress is indexed in the event), so it's
|
|
298
|
+
* a single RPC call regardless of how many tokens exist.
|
|
299
|
+
*/
|
|
300
|
+
getTokenEvent(tokenAddress: Address): Promise<TokenCreatedEvent | null>;
|
|
261
301
|
}
|
|
262
302
|
|
|
263
303
|
declare const ADDRESSES: {
|
|
@@ -335,6 +375,8 @@ declare const POOL_POSITIONS: {
|
|
|
335
375
|
*/
|
|
336
376
|
declare const DEFAULTS: {
|
|
337
377
|
readonly HOOK: `0x${string}`;
|
|
378
|
+
/** LP Locker with fee conversion (converts fees to ETH before distributing) */
|
|
379
|
+
readonly LOCKER: `0x${string}`;
|
|
338
380
|
readonly TICK_SPACING: 200;
|
|
339
381
|
readonly TICK_IF_TOKEN0_IS_LIQUID: -230400;
|
|
340
382
|
/** Static fee on buys (ETH → token): 1% (100 bps). Fees collected in ETH. */
|
|
@@ -2270,4 +2312,56 @@ interface SniperAuctionConfig {
|
|
|
2270
2312
|
*/
|
|
2271
2313
|
declare function encodeSniperAuctionData(config: SniperAuctionConfig): Hex;
|
|
2272
2314
|
|
|
2273
|
-
|
|
2315
|
+
/** Provenance — who launched the token and from where. */
|
|
2316
|
+
interface LiquidContext {
|
|
2317
|
+
/** System that deployed the token (e.g. "SDK", "Rainbow Wallet", "Liquid CLI") */
|
|
2318
|
+
interface: string;
|
|
2319
|
+
/** Social platform origin (e.g. "Farcaster", "Twitter") */
|
|
2320
|
+
platform?: string;
|
|
2321
|
+
/** Social post/message ID that triggered the deploy */
|
|
2322
|
+
messageId?: string;
|
|
2323
|
+
/** User ID on the originating platform */
|
|
2324
|
+
id?: string;
|
|
2325
|
+
}
|
|
2326
|
+
/** Social media link for token metadata. */
|
|
2327
|
+
interface SocialMediaUrl {
|
|
2328
|
+
platform: string;
|
|
2329
|
+
url: string;
|
|
2330
|
+
}
|
|
2331
|
+
/** Token info for aggregators and explorers. */
|
|
2332
|
+
interface LiquidMetadata {
|
|
2333
|
+
/** Token/project description */
|
|
2334
|
+
description?: string;
|
|
2335
|
+
/** Social media links */
|
|
2336
|
+
socialMediaUrls?: SocialMediaUrl[];
|
|
2337
|
+
/** Audit report URLs */
|
|
2338
|
+
auditUrls?: string[];
|
|
2339
|
+
}
|
|
2340
|
+
/**
|
|
2341
|
+
* Build a JSON string for the on-chain `context` field.
|
|
2342
|
+
*
|
|
2343
|
+
* @example
|
|
2344
|
+
* buildContext({ interface: "My App", platform: "Farcaster" })
|
|
2345
|
+
* // '{"interface":"My App","platform":"Farcaster"}'
|
|
2346
|
+
*/
|
|
2347
|
+
declare function buildContext(input?: Partial<LiquidContext>): string;
|
|
2348
|
+
/**
|
|
2349
|
+
* Build a JSON string for the on-chain `metadata` field.
|
|
2350
|
+
*
|
|
2351
|
+
* @example
|
|
2352
|
+
* buildMetadata({ description: "A cool token" })
|
|
2353
|
+
* // '{"description":"A cool token"}'
|
|
2354
|
+
*/
|
|
2355
|
+
declare function buildMetadata(input?: Partial<LiquidMetadata>): string;
|
|
2356
|
+
/**
|
|
2357
|
+
* Parse a context JSON string back into a typed object.
|
|
2358
|
+
* Returns `null` if the string is empty or not valid JSON.
|
|
2359
|
+
*/
|
|
2360
|
+
declare function parseContext(contextString: string): LiquidContext | null;
|
|
2361
|
+
/**
|
|
2362
|
+
* Parse a metadata JSON string back into a typed object.
|
|
2363
|
+
* Returns `null` if the string is empty or not valid JSON.
|
|
2364
|
+
*/
|
|
2365
|
+
declare function parseMetadata(metadataString: string): LiquidMetadata | null;
|
|
2366
|
+
|
|
2367
|
+
export { ADDRESSES, type AirdropInfo, 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, type GetTokensOptions, LiquidAirdropV2Abi, type LiquidContext, LiquidFactoryAbi, LiquidFeeLockerAbi, LiquidHookDynamicFeeV2Abi, LiquidLpLockerAbi, type LiquidMetadata, LiquidMevBlockDelayAbi, 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, buildContext, buildMetadata, createDefaultPositions, createPositions, createPositionsUSD, describePositions, encodeDynamicFeePoolData, encodeSniperAuctionData, encodeStaticFeePoolData, getTickFromMarketCapETH, getTickFromMarketCapStable, getTickFromMarketCapUSD, marketCapFromTickETH, marketCapFromTickUSD, parseContext, parseMetadata };
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,8 @@ __export(index_exports, {
|
|
|
44
44
|
LiquidVaultAbi: () => LiquidVaultAbi,
|
|
45
45
|
POOL_POSITIONS: () => POOL_POSITIONS,
|
|
46
46
|
TOKEN: () => TOKEN,
|
|
47
|
+
buildContext: () => buildContext,
|
|
48
|
+
buildMetadata: () => buildMetadata,
|
|
47
49
|
createDefaultPositions: () => createDefaultPositions,
|
|
48
50
|
createPositions: () => createPositions,
|
|
49
51
|
createPositionsUSD: () => createPositionsUSD,
|
|
@@ -55,7 +57,9 @@ __export(index_exports, {
|
|
|
55
57
|
getTickFromMarketCapStable: () => getTickFromMarketCapStable,
|
|
56
58
|
getTickFromMarketCapUSD: () => getTickFromMarketCapUSD,
|
|
57
59
|
marketCapFromTickETH: () => marketCapFromTickETH,
|
|
58
|
-
marketCapFromTickUSD: () => marketCapFromTickUSD
|
|
60
|
+
marketCapFromTickUSD: () => marketCapFromTickUSD,
|
|
61
|
+
parseContext: () => parseContext,
|
|
62
|
+
parseMetadata: () => parseMetadata
|
|
59
63
|
});
|
|
60
64
|
module.exports = __toCommonJS(index_exports);
|
|
61
65
|
|
|
@@ -147,6 +151,8 @@ var POOL_POSITIONS = {
|
|
|
147
151
|
};
|
|
148
152
|
var DEFAULTS = {
|
|
149
153
|
HOOK: ADDRESSES.HOOK_STATIC_FEE_V2,
|
|
154
|
+
/** LP Locker with fee conversion (converts fees to ETH before distributing) */
|
|
155
|
+
LOCKER: ADDRESSES.LP_LOCKER_FEE_CONVERSION,
|
|
150
156
|
TICK_SPACING: 200,
|
|
151
157
|
TICK_IF_TOKEN0_IS_LIQUID: -230400,
|
|
152
158
|
/** Static fee on buys (ETH → token): 1% (100 bps). Fees collected in ETH. */
|
|
@@ -255,6 +261,68 @@ function encodeSniperAuctionData(config) {
|
|
|
255
261
|
]);
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
// src/utils/context.ts
|
|
265
|
+
function buildContext(input) {
|
|
266
|
+
const ctx = {
|
|
267
|
+
interface: input?.interface ?? "SDK"
|
|
268
|
+
};
|
|
269
|
+
if (input?.platform !== void 0) ctx.platform = input.platform;
|
|
270
|
+
if (input?.messageId !== void 0) ctx.messageId = input.messageId;
|
|
271
|
+
if (input?.id !== void 0) ctx.id = input.id;
|
|
272
|
+
return JSON.stringify(ctx);
|
|
273
|
+
}
|
|
274
|
+
function buildMetadata(input) {
|
|
275
|
+
if (!input) return "{}";
|
|
276
|
+
const meta = {};
|
|
277
|
+
if (input.description !== void 0) meta.description = input.description;
|
|
278
|
+
if (input.socialMediaUrls !== void 0 && input.socialMediaUrls.length > 0) {
|
|
279
|
+
meta.socialMediaUrls = input.socialMediaUrls;
|
|
280
|
+
}
|
|
281
|
+
if (input.auditUrls !== void 0 && input.auditUrls.length > 0) {
|
|
282
|
+
meta.auditUrls = input.auditUrls;
|
|
283
|
+
}
|
|
284
|
+
return JSON.stringify(meta);
|
|
285
|
+
}
|
|
286
|
+
function parseContext(contextString) {
|
|
287
|
+
if (!contextString || contextString === "") return null;
|
|
288
|
+
try {
|
|
289
|
+
const parsed = JSON.parse(contextString);
|
|
290
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
291
|
+
return {
|
|
292
|
+
interface: typeof parsed.interface === "string" ? parsed.interface : "unknown",
|
|
293
|
+
...typeof parsed.platform === "string" && { platform: parsed.platform },
|
|
294
|
+
...typeof parsed.messageId === "string" && { messageId: parsed.messageId },
|
|
295
|
+
...typeof parsed.id === "string" && { id: parsed.id }
|
|
296
|
+
};
|
|
297
|
+
} catch {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function parseMetadata(metadataString) {
|
|
302
|
+
if (!metadataString || metadataString === "") return null;
|
|
303
|
+
try {
|
|
304
|
+
const parsed = JSON.parse(metadataString);
|
|
305
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
306
|
+
const result = {};
|
|
307
|
+
if (typeof parsed.description === "string") {
|
|
308
|
+
result.description = parsed.description;
|
|
309
|
+
}
|
|
310
|
+
if (Array.isArray(parsed.socialMediaUrls)) {
|
|
311
|
+
result.socialMediaUrls = parsed.socialMediaUrls.filter(
|
|
312
|
+
(item) => typeof item === "object" && item !== null && typeof item.platform === "string" && typeof item.url === "string"
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
if (Array.isArray(parsed.auditUrls)) {
|
|
316
|
+
result.auditUrls = parsed.auditUrls.filter(
|
|
317
|
+
(item) => typeof item === "string"
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
} catch {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
258
326
|
// src/abis/LiquidFactory.ts
|
|
259
327
|
var LiquidFactoryAbi = [
|
|
260
328
|
{
|
|
@@ -1154,7 +1222,7 @@ var LiquidSDK = class {
|
|
|
1154
1222
|
),
|
|
1155
1223
|
image: params.image ?? "",
|
|
1156
1224
|
metadata: params.metadata ?? "",
|
|
1157
|
-
context: params.context ??
|
|
1225
|
+
context: params.context ?? buildContext(),
|
|
1158
1226
|
originatingChainId: BigInt(DEFAULT_CHAIN_ID)
|
|
1159
1227
|
},
|
|
1160
1228
|
poolConfig: {
|
|
@@ -1168,7 +1236,7 @@ var LiquidSDK = class {
|
|
|
1168
1236
|
)
|
|
1169
1237
|
},
|
|
1170
1238
|
lockerConfig: {
|
|
1171
|
-
locker: params.locker ??
|
|
1239
|
+
locker: params.locker ?? DEFAULTS.LOCKER,
|
|
1172
1240
|
rewardAdmins: params.rewardAdmins ?? [account],
|
|
1173
1241
|
rewardRecipients: params.rewardRecipients ?? [account],
|
|
1174
1242
|
rewardBps: params.rewardBps ?? [1e4],
|
|
@@ -1558,7 +1626,7 @@ var LiquidSDK = class {
|
|
|
1558
1626
|
}
|
|
1559
1627
|
// ── LP Locker ───────────────────────────────────────────────────────
|
|
1560
1628
|
async getTokenRewards(tokenAddress, lockerAddress) {
|
|
1561
|
-
const locker = lockerAddress ??
|
|
1629
|
+
const locker = lockerAddress ?? DEFAULTS.LOCKER;
|
|
1562
1630
|
const result = await this.publicClient.readContract({
|
|
1563
1631
|
address: locker,
|
|
1564
1632
|
abi: LiquidLpLockerAbi,
|
|
@@ -1580,7 +1648,7 @@ var LiquidSDK = class {
|
|
|
1580
1648
|
if (!this.walletClient?.account) {
|
|
1581
1649
|
throw new Error("walletClient with account required for collectRewards");
|
|
1582
1650
|
}
|
|
1583
|
-
const locker = lockerAddress ??
|
|
1651
|
+
const locker = lockerAddress ?? DEFAULTS.LOCKER;
|
|
1584
1652
|
return await this.walletClient.writeContract({
|
|
1585
1653
|
address: locker,
|
|
1586
1654
|
abi: LiquidLpLockerAbi,
|
|
@@ -1596,7 +1664,7 @@ var LiquidSDK = class {
|
|
|
1596
1664
|
"walletClient with account required for collectRewardsWithoutUnlock"
|
|
1597
1665
|
);
|
|
1598
1666
|
}
|
|
1599
|
-
const locker = lockerAddress ??
|
|
1667
|
+
const locker = lockerAddress ?? DEFAULTS.LOCKER;
|
|
1600
1668
|
return await this.walletClient.writeContract({
|
|
1601
1669
|
address: locker,
|
|
1602
1670
|
abi: LiquidLpLockerAbi,
|
|
@@ -1612,7 +1680,7 @@ var LiquidSDK = class {
|
|
|
1612
1680
|
"walletClient with account required for updateRewardRecipient"
|
|
1613
1681
|
);
|
|
1614
1682
|
}
|
|
1615
|
-
const locker = lockerAddress ??
|
|
1683
|
+
const locker = lockerAddress ?? DEFAULTS.LOCKER;
|
|
1616
1684
|
return await this.walletClient.writeContract({
|
|
1617
1685
|
address: locker,
|
|
1618
1686
|
abi: LiquidLpLockerAbi,
|
|
@@ -1688,15 +1756,37 @@ var LiquidSDK = class {
|
|
|
1688
1756
|
* @param toBlock - Ending block to search to (defaults to 'latest')
|
|
1689
1757
|
*/
|
|
1690
1758
|
async getDeployedTokens(deployer, fromBlock, toBlock) {
|
|
1759
|
+
return this.getTokens({ deployer, fromBlock, toBlock });
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Query TokenCreated events with optional filtering.
|
|
1763
|
+
*
|
|
1764
|
+
* Use this for token discovery, indexing, or building token lists.
|
|
1765
|
+
* Returns events in chronological order with block numbers for pagination.
|
|
1766
|
+
*
|
|
1767
|
+
* @example
|
|
1768
|
+
* // Get all tokens
|
|
1769
|
+
* const allTokens = await sdk.getTokens();
|
|
1770
|
+
*
|
|
1771
|
+
* // Get tokens by deployer
|
|
1772
|
+
* const myTokens = await sdk.getTokens({ deployer: myAddress });
|
|
1773
|
+
*
|
|
1774
|
+
* // Paginate with block ranges
|
|
1775
|
+
* const page1 = await sdk.getTokens({ fromBlock: 20000000n, toBlock: 20100000n });
|
|
1776
|
+
* const page2 = await sdk.getTokens({ fromBlock: 20100001n, toBlock: 20200000n });
|
|
1777
|
+
*/
|
|
1778
|
+
async getTokens(options) {
|
|
1691
1779
|
const logs = await this.publicClient.getLogs({
|
|
1692
1780
|
address: ADDRESSES.FACTORY,
|
|
1693
1781
|
event: (0, import_viem2.parseAbiItem)(
|
|
1694
1782
|
"event TokenCreated(address msgSender, address indexed tokenAddress, address indexed tokenAdmin, string tokenImage, string tokenName, string tokenSymbol, string tokenMetadata, string tokenContext, int24 startingTick, address poolHook, bytes32 poolId, address pairedToken, address locker, address mevModule, uint256 extensionsSupply, address[] extensions)"
|
|
1695
1783
|
),
|
|
1696
|
-
fromBlock: fromBlock ?? 0n,
|
|
1697
|
-
toBlock: toBlock ?? "latest"
|
|
1784
|
+
fromBlock: options?.fromBlock ?? 0n,
|
|
1785
|
+
toBlock: options?.toBlock ?? "latest"
|
|
1698
1786
|
});
|
|
1787
|
+
const deployer = options?.deployer;
|
|
1699
1788
|
return logs.filter((log) => {
|
|
1789
|
+
if (!deployer) return true;
|
|
1700
1790
|
const sender = log.args.msgSender;
|
|
1701
1791
|
return sender && (0, import_viem2.getAddress)(sender) === (0, import_viem2.getAddress)(deployer);
|
|
1702
1792
|
}).map((log) => {
|
|
@@ -1717,10 +1807,54 @@ var LiquidSDK = class {
|
|
|
1717
1807
|
locker: args.locker,
|
|
1718
1808
|
mevModule: args.mevModule,
|
|
1719
1809
|
extensionsSupply: args.extensionsSupply,
|
|
1720
|
-
extensions: args.extensions
|
|
1810
|
+
extensions: args.extensions,
|
|
1811
|
+
blockNumber: log.blockNumber
|
|
1721
1812
|
};
|
|
1722
1813
|
});
|
|
1723
1814
|
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Look up a single token's on-chain event data by contract address.
|
|
1817
|
+
*
|
|
1818
|
+
* Returns the full TokenCreated event including metadata, context, poolId,
|
|
1819
|
+
* hook, locker, extensions — everything a wallet or aggregator needs to
|
|
1820
|
+
* display the token. Returns `null` if not found.
|
|
1821
|
+
*
|
|
1822
|
+
* This is indexed on-chain (tokenAddress is indexed in the event), so it's
|
|
1823
|
+
* a single RPC call regardless of how many tokens exist.
|
|
1824
|
+
*/
|
|
1825
|
+
async getTokenEvent(tokenAddress) {
|
|
1826
|
+
const logs = await this.publicClient.getLogs({
|
|
1827
|
+
address: ADDRESSES.FACTORY,
|
|
1828
|
+
event: (0, import_viem2.parseAbiItem)(
|
|
1829
|
+
"event TokenCreated(address msgSender, address indexed tokenAddress, address indexed tokenAdmin, string tokenImage, string tokenName, string tokenSymbol, string tokenMetadata, string tokenContext, int24 startingTick, address poolHook, bytes32 poolId, address pairedToken, address locker, address mevModule, uint256 extensionsSupply, address[] extensions)"
|
|
1830
|
+
),
|
|
1831
|
+
args: { tokenAddress },
|
|
1832
|
+
fromBlock: 0n,
|
|
1833
|
+
toBlock: "latest"
|
|
1834
|
+
});
|
|
1835
|
+
if (logs.length === 0) return null;
|
|
1836
|
+
const log = logs[0];
|
|
1837
|
+
const args = log.args;
|
|
1838
|
+
return {
|
|
1839
|
+
msgSender: args.msgSender,
|
|
1840
|
+
tokenAddress: args.tokenAddress,
|
|
1841
|
+
tokenAdmin: args.tokenAdmin,
|
|
1842
|
+
tokenImage: args.tokenImage,
|
|
1843
|
+
tokenName: args.tokenName,
|
|
1844
|
+
tokenSymbol: args.tokenSymbol,
|
|
1845
|
+
tokenMetadata: args.tokenMetadata,
|
|
1846
|
+
tokenContext: args.tokenContext,
|
|
1847
|
+
startingTick: args.startingTick,
|
|
1848
|
+
poolHook: args.poolHook,
|
|
1849
|
+
poolId: args.poolId,
|
|
1850
|
+
pairedToken: args.pairedToken,
|
|
1851
|
+
locker: args.locker,
|
|
1852
|
+
mevModule: args.mevModule,
|
|
1853
|
+
extensionsSupply: args.extensionsSupply,
|
|
1854
|
+
extensions: args.extensions,
|
|
1855
|
+
blockNumber: log.blockNumber
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1724
1858
|
};
|
|
1725
1859
|
|
|
1726
1860
|
// src/abis/LiquidUniv4EthDevBuy.ts
|
|
@@ -2006,6 +2140,8 @@ function describePositions(positions, ethPriceUSD) {
|
|
|
2006
2140
|
LiquidVaultAbi,
|
|
2007
2141
|
POOL_POSITIONS,
|
|
2008
2142
|
TOKEN,
|
|
2143
|
+
buildContext,
|
|
2144
|
+
buildMetadata,
|
|
2009
2145
|
createDefaultPositions,
|
|
2010
2146
|
createPositions,
|
|
2011
2147
|
createPositionsUSD,
|
|
@@ -2017,6 +2153,8 @@ function describePositions(positions, ethPriceUSD) {
|
|
|
2017
2153
|
getTickFromMarketCapStable,
|
|
2018
2154
|
getTickFromMarketCapUSD,
|
|
2019
2155
|
marketCapFromTickETH,
|
|
2020
|
-
marketCapFromTickUSD
|
|
2156
|
+
marketCapFromTickUSD,
|
|
2157
|
+
parseContext,
|
|
2158
|
+
parseMetadata
|
|
2021
2159
|
});
|
|
2022
2160
|
//# sourceMappingURL=index.js.map
|