liquid-sdk 1.7.1 → 1.7.3

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/dist/index.mjs CHANGED
@@ -103,7 +103,7 @@ var POOL_POSITIONS = {
103
103
  };
104
104
  var DEFAULTS = {
105
105
  HOOK: ADDRESSES.HOOK_STATIC_FEE_V2,
106
- /** LP Locker with fee conversion (converts fees to ETH before distributing) */
106
+ /** LP Locker with fee conversion (converts fees to WETH before distributing) */
107
107
  LOCKER: ADDRESSES.LP_LOCKER_FEE_CONVERSION,
108
108
  TICK_SPACING: 200,
109
109
  TICK_IF_TOKEN0_IS_LIQUID: -230400,
@@ -1143,6 +1143,73 @@ var LiquidSDK = class {
1143
1143
  extensionData
1144
1144
  };
1145
1145
  }
1146
+ // ── Airdrop Extension ──────────────────────────────────────────
1147
+ /**
1148
+ * Build an ExtensionConfig that reserves a percentage of supply into
1149
+ * the LiquidAirdropV2 contract for merkle-tree-based distribution.
1150
+ *
1151
+ * The airdrop contract expects `AirdropV2ExtensionData`:
1152
+ * { address admin, bytes32 merkleRoot, uint256 lockupDuration, uint256 vestingDuration }
1153
+ *
1154
+ * Leaf encoding used by LiquidAirdropV2.claim (note: **double hashed**
1155
+ * — OZ's standard 2nd-preimage-resistant pattern):
1156
+ * leaf = keccak256(bytes.concat(keccak256(abi.encode(recipient, allocatedAmount))))
1157
+ *
1158
+ * @example
1159
+ * ```typescript
1160
+ * const airdropExt = sdk.buildAirdropExtension({
1161
+ * admin: account.address,
1162
+ * merkleRoot: "0x…",
1163
+ * allocationBps: 2000, // 20%
1164
+ * lockupDuration: 86400, // 1 day (minimum)
1165
+ * vestingDuration: 0, // instant claim after lockup
1166
+ * });
1167
+ * ```
1168
+ */
1169
+ buildAirdropExtension(airdrop) {
1170
+ const MIN_LOCKUP = 86400;
1171
+ const MAX_BPS = 9e3;
1172
+ if (airdrop.allocationBps < 1 || airdrop.allocationBps > MAX_BPS) {
1173
+ throw new Error(
1174
+ `Airdrop allocationBps must be 1\u2013${MAX_BPS} (0.01%\u201390%). Got ${airdrop.allocationBps}.`
1175
+ );
1176
+ }
1177
+ if (airdrop.lockupDuration < MIN_LOCKUP) {
1178
+ throw new Error(
1179
+ `Airdrop lockupDuration must be \u2265 ${MIN_LOCKUP} seconds (1 day). Got ${airdrop.lockupDuration}.`
1180
+ );
1181
+ }
1182
+ if (airdrop.vestingDuration !== void 0 && airdrop.vestingDuration < 0) {
1183
+ throw new Error("Airdrop vestingDuration cannot be negative.");
1184
+ }
1185
+ const extensionData = encodeAbiParameters2(
1186
+ [
1187
+ {
1188
+ type: "tuple",
1189
+ components: [
1190
+ { type: "address", name: "admin" },
1191
+ { type: "bytes32", name: "merkleRoot" },
1192
+ { type: "uint256", name: "lockupDuration" },
1193
+ { type: "uint256", name: "vestingDuration" }
1194
+ ]
1195
+ }
1196
+ ],
1197
+ [
1198
+ {
1199
+ admin: airdrop.admin,
1200
+ merkleRoot: airdrop.merkleRoot,
1201
+ lockupDuration: BigInt(airdrop.lockupDuration),
1202
+ vestingDuration: BigInt(airdrop.vestingDuration ?? 0)
1203
+ }
1204
+ ]
1205
+ );
1206
+ return {
1207
+ extension: ADDRESSES.AIRDROP_V2,
1208
+ msgValue: 0n,
1209
+ extensionBps: airdrop.allocationBps,
1210
+ extensionData
1211
+ };
1212
+ }
1146
1213
  // ── Validation ─────────────────────────────────────────────────
1147
1214
  /**
1148
1215
  * Validate a DeploymentConfig before sending to the contract.
@@ -1307,13 +1374,27 @@ var LiquidSDK = class {
1307
1374
  (sum, ext) => sum + ext.msgValue,
1308
1375
  0n
1309
1376
  );
1377
+ let gas;
1378
+ try {
1379
+ const estimated = await this.publicClient.estimateContractGas({
1380
+ address: ADDRESSES.FACTORY,
1381
+ abi: LiquidFactoryAbi,
1382
+ functionName: "deployToken",
1383
+ args: [deploymentConfig],
1384
+ value: msgValue,
1385
+ account: this.walletClient.account
1386
+ });
1387
+ gas = estimated * 120n / 100n;
1388
+ } catch {
1389
+ gas = 6000000n;
1390
+ }
1310
1391
  const txHash = await this.walletClient.writeContract({
1311
1392
  address: ADDRESSES.FACTORY,
1312
1393
  abi: LiquidFactoryAbi,
1313
1394
  functionName: "deployToken",
1314
1395
  args: [deploymentConfig],
1315
1396
  value: msgValue,
1316
- gas: 5000000n,
1397
+ gas,
1317
1398
  chain: base2,
1318
1399
  account: this.walletClient.account
1319
1400
  });
@@ -1470,23 +1551,39 @@ var LiquidSDK = class {
1470
1551
  });
1471
1552
  }
1472
1553
  // ── Fee Claims ────────────────────────────────────────────────────
1473
- async getAvailableFees(feeOwner, tokenAddress) {
1554
+ /**
1555
+ * Get uncollected fees for a fee owner.
1556
+ * @param feeOwner - Address that receives fees (reward recipient)
1557
+ * @param feeToken - The token fees are denominated in. Defaults to WETH
1558
+ * (correct for all pools using LP_LOCKER_FEE_CONVERSION).
1559
+ */
1560
+ async getAvailableFees(feeOwner, feeToken = EXTERNAL.WETH) {
1474
1561
  return await this.publicClient.readContract({
1475
1562
  address: ADDRESSES.FEE_LOCKER,
1476
1563
  abi: LiquidFeeLockerAbi,
1477
1564
  functionName: "availableFees",
1478
- args: [feeOwner, tokenAddress]
1565
+ args: [feeOwner, feeToken]
1479
1566
  });
1480
1567
  }
1481
- async getFeesToClaim(feeOwner, tokenAddress) {
1568
+ /**
1569
+ * Get collected, claimable fees for a fee owner.
1570
+ * @param feeOwner - Address that receives fees (reward recipient)
1571
+ * @param feeToken - The token fees are denominated in. Defaults to WETH.
1572
+ */
1573
+ async getFeesToClaim(feeOwner, feeToken = EXTERNAL.WETH) {
1482
1574
  return await this.publicClient.readContract({
1483
1575
  address: ADDRESSES.FEE_LOCKER,
1484
1576
  abi: LiquidFeeLockerAbi,
1485
1577
  functionName: "feesToClaim",
1486
- args: [feeOwner, tokenAddress]
1578
+ args: [feeOwner, feeToken]
1487
1579
  });
1488
1580
  }
1489
- async claimFees(feeOwner, tokenAddress) {
1581
+ /**
1582
+ * Claim all accumulated fees for a fee owner.
1583
+ * @param feeOwner - Address that receives fees (reward recipient)
1584
+ * @param feeToken - The token fees are denominated in. Defaults to WETH.
1585
+ */
1586
+ async claimFees(feeOwner, feeToken = EXTERNAL.WETH) {
1490
1587
  if (!this.walletClient?.account) {
1491
1588
  throw new Error("walletClient with account required for claimFees");
1492
1589
  }
@@ -1494,7 +1591,7 @@ var LiquidSDK = class {
1494
1591
  address: ADDRESSES.FEE_LOCKER,
1495
1592
  abi: LiquidFeeLockerAbi,
1496
1593
  functionName: "claim",
1497
- args: [feeOwner, tokenAddress],
1594
+ args: [feeOwner, feeToken],
1498
1595
  chain: base2,
1499
1596
  account: this.walletClient.account
1500
1597
  });