@logswap/sdk 0.5.44 → 0.5.46

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.d.ts CHANGED
@@ -19,5 +19,5 @@ export * from "./onboard.js";
19
19
  export * from "./indexer.js";
20
20
  export * from "./tokencache.js";
21
21
  export * from "./fpool.js";
22
- export { cPoolManagerAbi, fPoolManagerAbi, logswapLensAbi, logswapRouterAbi } from "./generated.js";
22
+ export { cPoolManagerAbi, fPoolManagerAbi, logswapLensAbi, logswapRouterAbi, padHookAbi, polHookAbi, privateHookAbi, publicHookAbi } from "./generated.js";
23
23
  export * from "./admin.js";
package/dist/index.js CHANGED
@@ -19,5 +19,5 @@ export * from "./onboard.js";
19
19
  export * from "./indexer.js";
20
20
  export * from "./tokencache.js";
21
21
  export * from "./fpool.js";
22
- export { cPoolManagerAbi, fPoolManagerAbi, logswapLensAbi, logswapRouterAbi } from "./generated.js";
22
+ export { cPoolManagerAbi, fPoolManagerAbi, logswapLensAbi, logswapRouterAbi, padHookAbi, polHookAbi, privateHookAbi, publicHookAbi } from "./generated.js";
23
23
  export * from "./admin.js";
package/dist/indexer.js CHANGED
@@ -100,7 +100,7 @@ export async function indexerHealthy(url, signal) {
100
100
  */
101
101
  export async function discoverMarketsIndexed(url, signal) {
102
102
  const q = `{ allInitializes(first: 1000) { nodes {
103
- poolId base quote tickSpacing phiMin kappa alpha x0 blockNumber txHash
103
+ poolId base quote tickSpacing phi x0 blockNumber txHash
104
104
  } } }`;
105
105
  const d = await gql(url, q, undefined, signal);
106
106
  return d.allInitializes.nodes.map((n) => {
@@ -108,9 +108,7 @@ export async function discoverMarketsIndexed(url, signal) {
108
108
  base: n.base,
109
109
  quote: n.quote,
110
110
  tickSpacing: BigInt(n.tickSpacing),
111
- phiMin: BigInt(n.phiMin),
112
- kappa: BigInt(n.kappa),
113
- alpha: BigInt(n.alpha),
111
+ phi: BigInt(n.phi),
114
112
  };
115
113
  return {
116
114
  key,
@@ -142,7 +140,7 @@ export async function discoverMarketsBest(c, url, signal) {
142
140
  await c.public.readContract({
143
141
  address: c.addresses.cPoolManager,
144
142
  abi: cPoolManagerAbi,
145
- functionName: "phiEff",
143
+ functionName: "phiOf",
146
144
  args: [m.key],
147
145
  });
148
146
  return m;
package/dist/keys.d.ts CHANGED
@@ -20,18 +20,19 @@ export interface PoolKey {
20
20
  quote: Address;
21
21
  /** Log-tick spacing, WAD. The LP-boundary ladder — position floors and caps. */
22
22
  tickSpacing: bigint;
23
- /** Fee floor, WAD. `0n` selects `DEFAULT_FEE_MIN` (2 bp) at read time. */
24
- phiMin: bigint;
25
- /** Variance-fee coefficient, WAD. `0n` disables the dynamic fee. */
26
- kappa: bigint;
27
- /** EMA decay, WAD. `0n` selects `DEFAULT_ALPHA` (1/2) at read time. */
28
- alpha: bigint;
23
+ /**
24
+ * The swap fee, WAD, fixed for the life of the market: `FEE_MIN` (1 bp) ≤ φ ≤ `FEE_MAX` (25%),
25
+ * or `0n`, which selects `DEFAULT_FEE` (2 bp) at read time. Four fields since C version 4
26
+ * (decisions 042): `kappa` and `alpha` left with the variance kernel, and `phiMin` — a floor with
27
+ * nothing above it — became `phi`. Every pool id changed with the shape.
28
+ */
29
+ phi: bigint;
29
30
  }
30
31
  /**
31
32
  * `poolId = keccak256(abi.encode(key))` — the primary key of the entire read model.
32
33
  *
33
- * Note the zero-vs-default caveat the Solidity type documents: `phiMin` and `alpha` of `0` resolve
34
- * to their defaults at READ time, so a key carrying `0n` and one carrying the resolved default are
34
+ * Note the zero-vs-default caveat the Solidity type documents: a `phi` of `0` resolves to
35
+ * `DEFAULT_FEE` at READ time, so a key carrying `0n` and one carrying the resolved default are
35
36
  * DIFFERENT markets with different ids, even though they behave identically. Always address a
36
37
  * market by the key it was initialized with.
37
38
  */
package/dist/keys.js CHANGED
@@ -18,17 +18,15 @@ const POOL_KEY_ABI = [
18
18
  { name: "base", type: "address" },
19
19
  { name: "quote", type: "address" },
20
20
  { name: "tickSpacing", type: "int256" },
21
- { name: "phiMin", type: "uint256" },
22
- { name: "kappa", type: "uint256" },
23
- { name: "alpha", type: "uint256" },
21
+ { name: "phi", type: "uint256" },
24
22
  ],
25
23
  },
26
24
  ];
27
25
  /**
28
26
  * `poolId = keccak256(abi.encode(key))` — the primary key of the entire read model.
29
27
  *
30
- * Note the zero-vs-default caveat the Solidity type documents: `phiMin` and `alpha` of `0` resolve
31
- * to their defaults at READ time, so a key carrying `0n` and one carrying the resolved default are
28
+ * Note the zero-vs-default caveat the Solidity type documents: a `phi` of `0` resolves to
29
+ * `DEFAULT_FEE` at READ time, so a key carrying `0n` and one carrying the resolved default are
32
30
  * DIFFERENT markets with different ids, even though they behave identically. Always address a
33
31
  * market by the key it was initialized with.
34
32
  */
@@ -38,9 +36,7 @@ export function poolId(key) {
38
36
  base: key.base,
39
37
  quote: key.quote,
40
38
  tickSpacing: key.tickSpacing,
41
- phiMin: key.phiMin,
42
- kappa: key.kappa,
43
- alpha: key.alpha,
39
+ phi: key.phi,
44
40
  },
45
41
  ]));
46
42
  }
@@ -72,6 +72,8 @@ export interface ZapArgs extends WriteOptions {
72
72
  /** Fund entirely from base (true) or entirely from quote (false). */
73
73
  fundWithBase: boolean;
74
74
  amountIn: bigint;
75
+ /** The least the swap leg may return (contracts 7c82eed, decisions 043): the zap's own slippage bound, as `swapExactIn`'s. 0 = unbounded. */
76
+ minSwapOut?: bigint;
75
77
  targetFloor: bigint;
76
78
  cap?: bigint;
77
79
  L: bigint;
package/dist/liquidity.js CHANGED
@@ -94,6 +94,7 @@ export async function zapIn(c, a) {
94
94
  a.key,
95
95
  a.fundWithBase,
96
96
  a.amountIn,
97
+ a.minSwapOut ?? 0n,
97
98
  a.targetFloor,
98
99
  a.cap ?? NO_CAP,
99
100
  a.L,
package/dist/pools.d.ts CHANGED
@@ -26,9 +26,8 @@ export interface PoolState {
26
26
  reserveQuote: bigint;
27
27
  /** Fee-per-unit-L accumulator: $\phi \cdot \mathrm{TV}(\log p)$. */
28
28
  F: bigint;
29
- /** Quadratic variation of log-price, $\Sigma = \int (dx)^2$. */
29
+ /** Quadratic variation of log-price, $\Sigma = \sum_{\text{swaps}} (\Delta x_{\text{swap}})^2$ — one term per swap (decisions 042). */
30
30
  bigSigma: bigint;
31
- sigma2Ema: bigint;
32
31
  currentK: bigint;
33
32
  protocolOwed: bigint;
34
33
  minBackstopL: bigint;
@@ -36,8 +35,12 @@ export interface PoolState {
36
35
  }
37
36
  /** Read a market's full state by key. */
38
37
  export declare function getPool(c: LogswapClient, key: PoolKey): Promise<PoolState>;
39
- /** The effective fee right now: $\max(\phi_{\min}, \kappa\sqrt{\sigma^2_{\text{ema}}})$, capped. */
40
- export declare function phiEff(c: LogswapClient, key: PoolKey): Promise<bigint>;
38
+ /**
39
+ * The market's fee: the key's `phi` with `0n` resolved to `DEFAULT_FEE`. Constant for the market's
40
+ * life (C version 4, decisions 042 — `phiEff` and the variance kernel before). Reverts for a key
41
+ * nobody initialized, which `discoverMarkets` relies on to drop a stale indexer's rows.
42
+ */
43
+ export declare function phiOf(c: LogswapClient, key: PoolKey): Promise<bigint>;
41
44
  /**
42
45
  * Price from the stored log-price. **Lossy** — `x` is exact and this is a float, so use it for
43
46
  * display and never for arithmetic you intend to send back on-chain.
package/dist/pools.js CHANGED
@@ -25,12 +25,16 @@ export async function getPool(c, key) {
25
25
  });
26
26
  return v;
27
27
  }
28
- /** The effective fee right now: $\max(\phi_{\min}, \kappa\sqrt{\sigma^2_{\text{ema}}})$, capped. */
29
- export async function phiEff(c, key) {
28
+ /**
29
+ * The market's fee: the key's `phi` with `0n` resolved to `DEFAULT_FEE`. Constant for the market's
30
+ * life (C version 4, decisions 042 — `phiEff` and the variance kernel before). Reverts for a key
31
+ * nobody initialized, which `discoverMarkets` relies on to drop a stale indexer's rows.
32
+ */
33
+ export async function phiOf(c, key) {
30
34
  return c.public.readContract({
31
35
  address: c.addresses.cPoolManager,
32
36
  abi: cPoolManagerAbi,
33
- functionName: "phiEff",
37
+ functionName: "phiOf",
34
38
  args: [key],
35
39
  });
36
40
  }
@@ -88,9 +92,7 @@ export async function discoverMarkets(c, opts = {}) {
88
92
  base: a.base,
89
93
  quote: a.quote,
90
94
  tickSpacing: a.tickSpacing,
91
- phiMin: a.phiMin,
92
- kappa: a.kappa,
93
- alpha: a.alpha,
95
+ phi: a.phi,
94
96
  };
95
97
  return {
96
98
  key,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logswap/sdk",
3
- "version": "0.5.44",
3
+ "version": "0.5.46",
4
4
  "description": "TypeScript SDK for Logswap, the liquidity primitive introducing the logarithmic invariant — typed wrappers over the CPoolManager / FPoolManager / Router / Lens surface.",
5
5
  "license": "GPL-2.0-or-later",
6
6
  "type": "module",
package/src/admin.ts CHANGED
@@ -1,36 +1,89 @@
1
1
  /**
2
- * admin — the protocol's (feeCollector's) writes: the protocol's cuts, the harvest-cut exemption,
3
- * and the two-step collector handover, on both managers. Plain writes to the managers; no router.
4
- * One vocabulary (decisions 040): the C manager's `setProtocolFeeCut` / `PROTOCOL_FEE_CUT` are the
5
- * same words as F's `setFeeParams` / `MINT_FEE_PROTOCOL_CUT` until C version 4 renames them.
2
+ * admin — the protocol's (feeCollector's) writes: the protocol's cut of the mint fee on both
3
+ * managers, the hooks a pool of each kind may be born with, the hooks' own numbers, and the
4
+ * two-step collector handover. Plain writes to the managers and the hooks; no router.
5
+ *
6
+ * One vocabulary (decisions 040): both managers call the protocol's cut of the mint fee
7
+ * `MINT_FEE_PROTOCOL_CUT` and set it through `setFeeParams(uint256)` — one cut each since C
8
+ * version 4 / F version 14. The harvest's cut is the hook's answer at every harvest (decisions
9
+ * 044), set on the hook (`setHarvestCut`) and capped by the manager (`HARVEST_CUT_MAX`); the
10
+ * release's protocol share likewise (`POT_CUT_MAX`).
6
11
  */
7
12
 
8
- import type { Address, Hash, Hex } from "viem";
13
+ import type { Address, Hash } from "viem";
9
14
  import type { LogswapClient } from "./client.js";
10
- import { cPoolManagerAbi, fPoolManagerAbi } from "./generated.js";
15
+ import { cPoolManagerAbi, fPoolManagerAbi, padHookAbi, polHookAbi, publicHookAbi } from "./generated.js";
16
+ import { F_KIND, fHookBaseAbi, type FPoolKind } from "./fpool.js";
11
17
 
12
18
  function wallet(c: LogswapClient) {
13
19
  if (!c.wallet) throw new Error("a wallet client is required");
14
20
  return c.wallet;
15
21
  }
16
22
 
17
- export async function setProtocolFeeCut(c: LogswapClient, cutWad: bigint): Promise<Hash> {
18
- return wallet(c).writeContract({ address: c.addresses.cPoolManager, abi: cPoolManagerAbi, functionName: "setProtocolFeeCut", args: [cutWad], chain: c.wallet!.chain, account: c.wallet!.account! } as never);
23
+ function write(c: LogswapClient, address: Address, abi: readonly unknown[], functionName: string, args: readonly unknown[]): Promise<Hash> {
24
+ return wallet(c).writeContract({ address, abi, functionName, args, chain: c.wallet!.chain, account: c.wallet!.account! } as never);
19
25
  }
20
- export async function setFeeParams(c: LogswapClient, mintFeeProtocolCutWad: bigint, harvestProtocolCutWad: bigint): Promise<Hash> {
21
- return wallet(c).writeContract({ address: c.addresses.fPoolManager as Address, abi: fPoolManagerAbi, functionName: "setFeeParams", args: [mintFeeProtocolCutWad, harvestProtocolCutWad], chain: c.wallet!.chain, account: c.wallet!.account! } as never);
26
+
27
+ /** The C manager's `setFeeParams(mintFeeProtocolCut)` — one cut. */
28
+ export async function setFeeParamsC(c: LogswapClient, mintFeeProtocolCutWad: bigint): Promise<Hash> {
29
+ return write(c, c.addresses.cPoolManager, cPoolManagerAbi, "setFeeParams", [mintFeeProtocolCutWad]);
30
+ }
31
+ /** The F manager's `setFeeParams(mintFeeProtocolCut)` — one cut, the C manager's shape (F version 14). */
32
+ export async function setFeeParams(c: LogswapClient, mintFeeProtocolCutWad: bigint): Promise<Hash> {
33
+ return write(c, c.addresses.fPoolManager as Address, fPoolManagerAbi, "setFeeParams", [mintFeeProtocolCutWad]);
34
+ }
35
+
36
+ /**
37
+ * Approve a hook for pools of `kind` to be born with, or withdraw the approval (decisions 041,
38
+ * 044). Read at `initialize` and never again: a live pool keeps its hook.
39
+ */
40
+ export async function setHookApproved(c: LogswapClient, kind: FPoolKind, hook: Address, approved: boolean): Promise<Hash> {
41
+ return write(c, c.addresses.fPoolManager as Address, fPoolManagerAbi, "setHookApproved", [F_KIND[kind], hook, approved]);
42
+ }
43
+
44
+ /** Whether `hook` is approved for pools of `kind`. */
45
+ export async function hookApproved(c: LogswapClient, kind: FPoolKind, hook: Address): Promise<boolean> {
46
+ return c.public.readContract({ address: c.addresses.fPoolManager as Address, abi: fPoolManagerAbi, functionName: "hookApproved", args: [F_KIND[kind], hook] } as never) as Promise<boolean>;
22
47
  }
23
- /** Waive the protocol's cut of harvested income for one pool (`HARVEST_PROTOCOL_CUT`; F version 13 — `setHarvestFeeExempt` before). */
24
- export async function setHarvestCutExempt(c: LogswapClient, poolId: Hex, exempt: boolean): Promise<Hash> {
25
- return wallet(c).writeContract({ address: c.addresses.fPoolManager as Address, abi: fPoolManagerAbi, functionName: "setHarvestCutExempt", args: [poolId, exempt], chain: c.wallet!.chain, account: c.wallet!.account! } as never);
48
+
49
+ // ─── the hooks' numbers (the collector's; each bounded where it reaches the manager) ─────
50
+
51
+ /** The protocol's rate on the income part of every harvest under `hook`, WAD ≤ `HARVEST_CUT_MAX`. */
52
+ export async function setHarvestCut(c: LogswapClient, hook: Address, rateWad: bigint): Promise<Hash> {
53
+ return write(c, hook, fHookBaseAbi, "setHarvestCut", [rateWad]);
26
54
  }
55
+
56
+ /** `PadHook.setSchedule`: `T(0)`, the rung's growth, the creator's and the protocol's shares of the pot (≤ `POT_CUT_MAX`), the burn per rung (≤ `BURN_MAX`). */
57
+ export async function padSetSchedule(
58
+ c: LogswapClient,
59
+ hook: Address,
60
+ s: { thresholdBase: bigint; thresholdGrowth: bigint; creatorShare: bigint; protocolShare: bigint; burnPerRung: bigint },
61
+ ): Promise<Hash> {
62
+ return write(c, hook, padHookAbi, "setSchedule", [s.thresholdBase, s.thresholdGrowth, s.creatorShare, s.protocolShare, s.burnPerRung]);
63
+ }
64
+
65
+ /** `PolHook.setPolicy`: what every harvest leaves in the bid and what a relaunch's seed must bring, WAD fractions of L. */
66
+ export async function polSetPolicy(c: LogswapClient, hook: Address, s: { keepQuote: bigint; minQuoteAtSeed: bigint }): Promise<Hash> {
67
+ return write(c, hook, polHookAbi, "setPolicy", [s.keepQuote, s.minQuoteAtSeed]);
68
+ }
69
+
70
+ /** `PublicHook.setListed`: an asset a curated seed may hold. */
71
+ export async function publicSetListed(c: LogswapClient, hook: Address, token: Address, listed: boolean): Promise<Hash> {
72
+ return write(c, hook, publicHookAbi, "setListed", [token, listed]);
73
+ }
74
+
75
+ /** `PublicHook.setCurated`: whether every public seed is checked against the list. */
76
+ export async function publicSetCurated(c: LogswapClient, hook: Address, curated: boolean): Promise<Hash> {
77
+ return write(c, hook, publicHookAbi, "setCurated", [curated]);
78
+ }
79
+
27
80
  export async function proposeCollector(c: LogswapClient, side: "C" | "F", next: Address): Promise<Hash> {
28
81
  const address = side === "C" ? c.addresses.cPoolManager : (c.addresses.fPoolManager as Address);
29
82
  const abi = side === "C" ? cPoolManagerAbi : fPoolManagerAbi;
30
- return wallet(c).writeContract({ address, abi, functionName: "proposeCollector", args: [next], chain: c.wallet!.chain, account: c.wallet!.account! } as never);
83
+ return write(c, address, abi, "proposeCollector", [next]);
31
84
  }
32
85
  export async function acceptCollector(c: LogswapClient, side: "C" | "F"): Promise<Hash> {
33
86
  const address = side === "C" ? c.addresses.cPoolManager : (c.addresses.fPoolManager as Address);
34
87
  const abi = side === "C" ? cPoolManagerAbi : fPoolManagerAbi;
35
- return wallet(c).writeContract({ address, abi, functionName: "acceptCollector", args: [], chain: c.wallet!.chain, account: c.wallet!.account! } as never);
88
+ return write(c, address, abi, "acceptCollector", []);
36
89
  }
package/src/client.ts CHANGED
@@ -23,6 +23,14 @@ export interface LogswapAddresses {
23
23
  * deployment predating it will not carry the address; every F-pool call needs it.
24
24
  */
25
25
  fPoolManager?: Address;
26
+ /**
27
+ * The protocol's four F hooks, one per kind (decisions 044): every F pool names one in its key,
28
+ * and the pool's roles, gates and terms live on it. A deployment predating them carries none.
29
+ */
30
+ publicHook?: Address;
31
+ privateHook?: Address;
32
+ polHook?: Address;
33
+ padHook?: Address;
26
34
  /** Optional — the router falls back to plain approvals when absent. */
27
35
  permit2?: Address;
28
36
  }
@@ -58,8 +66,13 @@ export function createLogswapClient(args: {
58
66
  * **3** since 2026-09-03 (contracts `d8406fb`): `burnById` and `update` take an `owner`, `update`
59
67
  * mints to `to`, `positions()` returns `aps` as uint128 — and a returned quote flow now carries the
60
68
  * swept fees (decisions 018), which is why `exit`'s settle-to-one-asset math changed with it.
69
+ *
70
+ * **4** since 2026-09-18 (decisions 042 + 040): `PoolKey` is `(base, quote, tickSpacing, phi)` —
71
+ * the variance kernel and its two key fields are gone, so every pool id changed; `phiEff` is
72
+ * `phiOf`; `getPool` lost `sigma2Ema`; `Initialize` lost two fields; the cut is
73
+ * `MINT_FEE_PROTOCOL_CUT` / `setFeeParams`.
61
74
  */
62
- export const EXPECTED_VERSION = 3n;
75
+ export const EXPECTED_VERSION = 4n;
63
76
  /**
64
77
  * The F manager's own tag (contracts 25a7bcf: 5 — the key's salt, pool names, the sponsor registry;
65
78
  * 4 was the income-only harvest cut).
@@ -97,7 +110,16 @@ export const EXPECTED_VERSION = 3n;
97
110
  // is voided by the handover of the role that granted it); `setLegs` needs a generation to have
98
111
  // lived (`gen > 0`); `initialize` refuses a codeless base and `mint` refuses `to = address(0)`
99
112
  // on both managers. Layout unchanged.
100
- export const EXPECTED_F_VERSION = 13n;
113
+ // 14 (2026-09-20): the hook (decisions 041) — `FPoolKey.hook`, every pool id moves; `dissolve` is
114
+ // `retire`, `regenerate` releases the dead shares' pot, `harvestable`/`unharvested` are the
115
+ // readouts; `feePerL`, `edgePerL`, `HARVEST_PROTOCOL_CUT`, `harvestCutExempt` are gone.
116
+ // 15 (2026-09-20): the hook answers every question (decisions 044) — `FPoolKey.authority` is
117
+ // `creator` (every pool id moves again); the roles, gates and list are the pool's HOOK's
118
+ // (`FHookBase` / `PrivateHook`), not the manager's: `getPool` has `hook` and `asks` and no
119
+ // role; `proposeAuthority`, `appointOperator`, `setGates`, `setAllowed` are hook writes;
120
+ // `hookApproved(kind, hook)` / `setHookApproved(kind, hook, ok)`; `Regenerated` names the payee;
121
+ // `HARVEST_CUT_MAX` / `POT_CUT_MAX` cap what a hook may route to the protocol.
122
+ export const EXPECTED_F_VERSION = 15n;
101
123
 
102
124
  export async function assertVersion(c: LogswapClient, expected = EXPECTED_VERSION): Promise<void> {
103
125
  const { cPoolManagerAbi } = await import("./generated.js");