@logswap/sdk 0.5.48 → 0.5.50
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/admin.d.ts +44 -4
- package/dist/admin.js +79 -8
- package/dist/client.d.ts +7 -1
- package/dist/client.js +8 -2
- package/dist/fpool.d.ts +40 -8
- package/dist/fpool.js +40 -23
- package/dist/generated.d.ts +597 -130
- package/dist/generated.js +376 -55
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/admin.ts +97 -8
- package/src/client.ts +14 -2
- package/src/fpool.ts +49 -28
- package/src/generated.ts +378 -55
- package/src/index.ts +1 -1
package/src/admin.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
import type { Address, Hash } from "viem";
|
|
14
14
|
import type { LogswapClient } from "./client.js";
|
|
15
|
-
import { cPoolManagerAbi, fPoolManagerAbi, padPolicyAbi, polPolicyAbi, publicPolicyAbi } from "./generated.js";
|
|
16
|
-
import { F_KIND, fPolicyBaseAbi, type FPoolKind } from "./fpool.js";
|
|
15
|
+
import { cPoolManagerAbi, fPoolManagerAbi, padPolicyAbi, polPolicyAbi, policyRegistryAbi, publicPolicyAbi } from "./generated.js";
|
|
16
|
+
import { F_KIND, bytes32ToText, fPolicyBaseAbi, textToBytes32, type FPoolKind } from "./fpool.js";
|
|
17
17
|
|
|
18
18
|
function wallet(c: LogswapClient) {
|
|
19
19
|
if (!c.wallet) throw new Error("a wallet client is required");
|
|
@@ -33,17 +33,106 @@ export async function setFeeParams(c: LogswapClient, mintFeeProtocolCutWad: bigi
|
|
|
33
33
|
return write(c, c.addresses.fPoolManager as Address, fPoolManagerAbi, "setFeeParams", [mintFeeProtocolCutWad]);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// ─── the registry (decisions 046): the LOG authority's, not the collector's ─────────────────
|
|
37
|
+
|
|
38
|
+
const ZERO = "0x0000000000000000000000000000000000000000" as const;
|
|
39
|
+
|
|
36
40
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
41
|
+
* The policy registry the F manager asks at every birth — `addresses.policyRegistry` when the
|
|
42
|
+
* deployment carries it, else read once from the manager. The zero address is a deployment with
|
|
43
|
+
* no registry: it asks nobody, and nothing here can be written.
|
|
39
44
|
*/
|
|
40
|
-
export async function
|
|
41
|
-
|
|
45
|
+
export async function policyRegistryOf(c: LogswapClient): Promise<Address> {
|
|
46
|
+
if (c.addresses.policyRegistry) return c.addresses.policyRegistry;
|
|
47
|
+
return (await c.public.readContract({ address: c.addresses.fPoolManager as Address, abi: fPoolManagerAbi, functionName: "registry" } as never)) as Address;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
/** Whether `policy` is approved for pools of `kind
|
|
50
|
+
/** Whether `policy` is approved for pools of `kind` now — listed and not yet sunset. True everywhere on a deployment with no registry. */
|
|
45
51
|
export async function policyApproved(c: LogswapClient, kind: FPoolKind, policy: Address): Promise<boolean> {
|
|
46
|
-
|
|
52
|
+
const registry = await policyRegistryOf(c);
|
|
53
|
+
if (registry === ZERO) return true;
|
|
54
|
+
return c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "isApproved", args: [F_KIND[kind], policy] } as never) as Promise<boolean>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** One policy on a kind's list, as the registry holds it. */
|
|
58
|
+
export interface RegistryEntry {
|
|
59
|
+
policy: Address;
|
|
60
|
+
name: string;
|
|
61
|
+
/** The block it closes to new pools from; 0 = open. */
|
|
62
|
+
until: bigint;
|
|
63
|
+
/** Approved now: listed and not yet sunset. */
|
|
64
|
+
approved: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Every policy listed for `kind`, sunset ones included — what a create form's dropdown reads. Empty with no registry. */
|
|
68
|
+
export async function registryPolicies(c: LogswapClient, kind: FPoolKind): Promise<RegistryEntry[]> {
|
|
69
|
+
const registry = await policyRegistryOf(c);
|
|
70
|
+
if (registry === ZERO) return [];
|
|
71
|
+
const list = (await c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "policiesOf", args: [F_KIND[kind]] } as never)) as readonly Address[];
|
|
72
|
+
const block = await c.public.getBlockNumber();
|
|
73
|
+
return Promise.all(
|
|
74
|
+
list.map(async (policy) => {
|
|
75
|
+
const [listed, until, , name] = (await c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "entries", args: [F_KIND[kind], policy] } as never)) as [boolean, bigint, number, `0x${string}`];
|
|
76
|
+
return { policy, name: bytes32ToText(name), until, approved: listed && (until === 0n || block < until) };
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The registry's owner — the LOG authority — and the proposed next one. */
|
|
82
|
+
export async function registryOwner(c: LogswapClient): Promise<{ owner: Address; pending: Address }> {
|
|
83
|
+
const registry = await policyRegistryOf(c);
|
|
84
|
+
if (registry === ZERO) return { owner: ZERO, pending: ZERO };
|
|
85
|
+
const [owner, pending] = await Promise.all([
|
|
86
|
+
c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "owner" } as never) as Promise<Address>,
|
|
87
|
+
c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "pendingOwner" } as never) as Promise<Address>,
|
|
88
|
+
]);
|
|
89
|
+
return { owner, pending };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function registryWrite(c: LogswapClient, functionName: string, args: readonly unknown[]): Promise<Hash> {
|
|
93
|
+
const registry = await policyRegistryOf(c);
|
|
94
|
+
if (registry === ZERO) throw new Error("logswap: this deployment carries no policy registry");
|
|
95
|
+
return write(c, registry, policyRegistryAbi, functionName, args);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** `PolicyRegistry.approve`: list `policy` for pools of `kind`, under `name` (at most 31 bytes). Again renames it and clears its sunset. The owner's. */
|
|
99
|
+
export async function registryApprove(c: LogswapClient, kind: FPoolKind, policy: Address, name: string): Promise<Hash> {
|
|
100
|
+
return registryWrite(c, "approve", [F_KIND[kind], policy, textToBytes32(name)]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** `PolicyRegistry.sunset`: close `policy` to new pools of `kind` from `untilBlock` on; 0 reopens. The owner's. */
|
|
104
|
+
export async function registrySunset(c: LogswapClient, kind: FPoolKind, policy: Address, untilBlock: bigint): Promise<Hash> {
|
|
105
|
+
return registryWrite(c, "sunset", [F_KIND[kind], policy, untilBlock]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** `PolicyRegistry.revoke`: remove `policy` from `kind`'s list at once. Live pools are untouched. The owner's. */
|
|
109
|
+
export async function registryRevoke(c: LogswapClient, kind: FPoolKind, policy: Address): Promise<Hash> {
|
|
110
|
+
return registryWrite(c, "revoke", [F_KIND[kind], policy]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The registry owner's two-step handover. */
|
|
114
|
+
export async function registryProposeOwner(c: LogswapClient, next: Address): Promise<Hash> {
|
|
115
|
+
return registryWrite(c, "proposeOwner", [next]);
|
|
116
|
+
}
|
|
117
|
+
export async function registryAcceptOwner(c: LogswapClient): Promise<Hash> {
|
|
118
|
+
return registryWrite(c, "acceptOwner", []);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Approve or revoke, the F version 15–16 shape kept for callers: `approved` true is
|
|
123
|
+
* {@link registryApprove} under the kind's name, false is {@link registryRevoke}.
|
|
124
|
+
*/
|
|
125
|
+
export async function setPolicyApproved(c: LogswapClient, kind: FPoolKind, policy: Address, approved: boolean): Promise<Hash> {
|
|
126
|
+
return approved ? registryApprove(c, kind, policy, kind) : registryRevoke(c, kind, policy);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Move a pool to another policy the registry approves for its kind (decisions 046): the registry
|
|
131
|
+
* owner's alone. The new policy takes the authority from the old; the operator and the lists
|
|
132
|
+
* void; no swap lands in the block.
|
|
133
|
+
*/
|
|
134
|
+
export async function fPoolMigrate(c: LogswapClient, a: { poolId: `0x${string}`; to: Address }): Promise<Hash> {
|
|
135
|
+
return write(c, c.addresses.fPoolManager as Address, fPoolManagerAbi, "migrate", [a.poolId, a.to]);
|
|
47
136
|
}
|
|
48
137
|
|
|
49
138
|
// ─── the policies' numbers (the collector's; each bounded where it reaches the manager) ─────
|
package/src/client.ts
CHANGED
|
@@ -31,6 +31,12 @@ export interface LogswapAddresses {
|
|
|
31
31
|
privatePolicy?: Address;
|
|
32
32
|
polPolicy?: Address;
|
|
33
33
|
padPolicy?: Address;
|
|
34
|
+
/**
|
|
35
|
+
* The policy registry (decisions 046): what a pool of each kind may be born under, and the
|
|
36
|
+
* owner that may move a pool between policies. Read from the F manager (`registry()`) when
|
|
37
|
+
* absent; a deployment with none asks nobody.
|
|
38
|
+
*/
|
|
39
|
+
policyRegistry?: Address;
|
|
34
40
|
/** Optional — the router falls back to plain approvals when absent. */
|
|
35
41
|
permit2?: Address;
|
|
36
42
|
}
|
|
@@ -116,13 +122,19 @@ export const EXPECTED_VERSION = 4n;
|
|
|
116
122
|
// 15 (2026-09-20): the policy answers every question (decisions 044) — `FPoolKey.authority` is
|
|
117
123
|
// `creator` (every pool id moves again); the roles, gates and list are the pool's POLICY's
|
|
118
124
|
// (`FPolicyBase` / `PrivatePolicy`), not the manager's: `getPool` has `policy` and `asks` and no
|
|
119
|
-
// role; `proposeAuthority`, `appointOperator`, `setGates`, `setAllowed` are policy writes;
|
|
125
|
+
// role; `proposeAuthority`, `appointOperator`, `setGates`, `setAllowed` (`setMinters` / `setTakers` since 17) are policy writes;
|
|
120
126
|
// `policyApproved(kind, policy)` / `setPolicyApproved(kind, policy, ok)`; `Regenerated` names the payee;
|
|
121
127
|
// `HARVEST_CUT_MAX` / `POT_CUT_MAX` cap what a policy may route to the protocol.
|
|
122
128
|
// 16 (2026-09-21): the word is POLICY (decisions 045) — a rename, no pool id moves: `FPoolKey.policy`,
|
|
123
129
|
// `IFPolicy`, `FPolicyBase`, `PublicPolicy` … `PadPolicy`, `policyApproved` / `setPolicyApproved`,
|
|
124
130
|
// `PolicyApproved`; `PolPolicy.setPolicy` / `PolicySet` are `setRules` / `RulesSet`.
|
|
125
|
-
|
|
131
|
+
// 17 (2026-09-21): the registry, the move, the stamp, two lists, one base (decisions 046–048) — no
|
|
132
|
+
// pool id moves: the F manager takes a `PolicyRegistry` at construction and asks it at a birth
|
|
133
|
+
// (`policyApproved` / `setPolicyApproved` left the manager: `registryApprove` …); the key's policy
|
|
134
|
+
// is the policy at birth, `migrate` moves a pool for the registry's owner; `stamp` / `setAsks` are
|
|
135
|
+
// the policy's; the desk's `setAllowed` / `isAllowed` are `setMinters` / `setTakers` / `isMinter` /
|
|
136
|
+
// `isTaker`; a pad and a POL hold one base (`OneBase`).
|
|
137
|
+
export const EXPECTED_F_VERSION = 17n;
|
|
126
138
|
|
|
127
139
|
export async function assertVersion(c: LogswapClient, expected = EXPECTED_VERSION): Promise<void> {
|
|
128
140
|
const { cPoolManagerAbi } = await import("./generated.js");
|
package/src/fpool.ts
CHANGED
|
@@ -1142,15 +1142,15 @@ export function fPoolLaunchCalls(
|
|
|
1142
1142
|
}
|
|
1143
1143
|
|
|
1144
1144
|
/**
|
|
1145
|
-
* The desk's opening posture, on its policy (decisions 044): gated minting, the creator
|
|
1146
|
-
* appointment: the authority is the operator until one is appointed (decisions 037).
|
|
1147
|
-
* to `PrivatePolicy`; the launch batch cannot carry them (they are not manager calls).
|
|
1145
|
+
* The desk's opening posture, on its policy (decisions 044, 048): gated minting, the creator a
|
|
1146
|
+
* minter. No appointment: the authority is the operator until one is appointed (decisions 037).
|
|
1147
|
+
* Two writes to `PrivatePolicy`; the launch batch cannot carry them (they are not manager calls).
|
|
1148
1148
|
*/
|
|
1149
1149
|
export async function fPoolDeskOpening(c: LogswapClient, a: { poolId: Hex; account: Address; policy?: Address }): Promise<Hash[]> {
|
|
1150
1150
|
const policy = a.policy ?? fPoolPolicyFor(c, "private");
|
|
1151
1151
|
return [
|
|
1152
1152
|
await fPoolSetGates(c, { poolId: a.poolId, gateMint: true, gateSwap: false, account: a.account, policy }),
|
|
1153
|
-
await
|
|
1153
|
+
await fPoolSetMinters(c, { poolId: a.poolId, who: [a.account], allowed: true, account: a.account, policy }),
|
|
1154
1154
|
];
|
|
1155
1155
|
}
|
|
1156
1156
|
|
|
@@ -1229,25 +1229,44 @@ export async function fPoolSetGates(
|
|
|
1229
1229
|
}
|
|
1230
1230
|
|
|
1231
1231
|
/**
|
|
1232
|
-
* Add to or remove from the pool's
|
|
1233
|
-
*
|
|
1232
|
+
* Add to or remove from the pool's MINTERS — who may mint, and swap (a zap in is both under one
|
|
1233
|
+
* lock) — in one call (the authority, on the desk's policy; decisions 048). The list is keyed by
|
|
1234
|
+
* the authority that granted it: a handover starts the buyer with an empty one. Stamps the
|
|
1235
|
+
* block: no swap lands in it (047).
|
|
1234
1236
|
*/
|
|
1235
|
-
export async function
|
|
1237
|
+
export async function fPoolSetMinters(
|
|
1236
1238
|
c: LogswapClient,
|
|
1237
1239
|
a: { poolId: Hex; who: readonly Address[]; allowed: boolean; account: Address; policy?: Address },
|
|
1238
1240
|
) {
|
|
1239
|
-
return writePolicy(c, privatePolicyAbi, a, "
|
|
1241
|
+
return writePolicy(c, privatePolicyAbi, a, "setMinters", [a.who, a.allowed]);
|
|
1240
1242
|
}
|
|
1241
1243
|
|
|
1242
|
-
/**
|
|
1243
|
-
export async function
|
|
1244
|
+
/** Add to or remove from the pool's TAKERS — who may swap only — in one call (the authority; decisions 048). Stamps the block. */
|
|
1245
|
+
export async function fPoolSetTakers(
|
|
1246
|
+
c: LogswapClient,
|
|
1247
|
+
a: { poolId: Hex; who: readonly Address[]; allowed: boolean; account: Address; policy?: Address },
|
|
1248
|
+
) {
|
|
1249
|
+
return writePolicy(c, privatePolicyAbi, a, "setTakers", [a.who, a.allowed]);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
async function readDesk<T>(c: LogswapClient, poolId: Hex, who: Address, functionName: string, policy?: Address): Promise<T> {
|
|
1244
1253
|
const address = policy ?? (await fPoolPolicyOf(c, poolId));
|
|
1245
|
-
return (await c.public.readContract({
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1254
|
+
return (await c.public.readContract({ address, abi: privatePolicyAbi, functionName, args: [poolId, who] } as never)) as T;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/** On the pool's minters under its current authority: may mint, and swap. */
|
|
1258
|
+
export async function fPoolIsMinter(c: LogswapClient, poolId: Hex, who: Address, policy?: Address): Promise<boolean> {
|
|
1259
|
+
return readDesk<boolean>(c, poolId, who, "isMinter", policy);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/** On the pool's takers under its current authority: may swap only. */
|
|
1263
|
+
export async function fPoolIsTaker(c: LogswapClient, poolId: Hex, who: Address, policy?: Address): Promise<boolean> {
|
|
1264
|
+
return readDesk<boolean>(c, poolId, who, "isTaker", policy);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
/** May swap: a minter or a taker (consulted only while the swap gate is on). */
|
|
1268
|
+
export async function fPoolIsAllowed(c: LogswapClient, poolId: Hex, who: Address, policy?: Address): Promise<boolean> {
|
|
1269
|
+
return readDesk<boolean>(c, poolId, who, "isAllowed", policy);
|
|
1251
1270
|
}
|
|
1252
1271
|
|
|
1253
1272
|
/** Label the pool — the sponsor's own words, mutable, never identity. At most 31 bytes of UTF-8. */
|
|
@@ -1346,7 +1365,7 @@ export interface DiscoveredFPool {
|
|
|
1346
1365
|
weights: bigint[];
|
|
1347
1366
|
phi: bigint;
|
|
1348
1367
|
kind: FPoolKind;
|
|
1349
|
-
/** The pool's policy — the contract the key names (decisions 041, 044, 045). */
|
|
1368
|
+
/** The pool's policy AT BIRTH — the contract the key names (decisions 041, 044, 045). The LIVE one is {@link getFPool}'s `policy`: the registry's owner may have moved the pool (046, `PolicyMigrated`). */
|
|
1350
1369
|
policy: Address;
|
|
1351
1370
|
/** Who was born holding the pool (immutable). The LIVE authority is the policy's — {@link getFPoolRoles}. */
|
|
1352
1371
|
creator: Address;
|
|
@@ -1483,20 +1502,22 @@ export async function fPoolsControlledBy(
|
|
|
1483
1502
|
opts: { pools?: DiscoveredFPool[]; fromBlock?: bigint } = {},
|
|
1484
1503
|
): Promise<FPoolControlled[]> {
|
|
1485
1504
|
const pools = opts.pools ?? (await discoverFPools(c, { fromBlock: opts.fromBlock }));
|
|
1505
|
+
// the LIVE policy answers for the authority: a moved pool (046) is on another one than its birth's
|
|
1506
|
+
const states = await Promise.all(pools.map((p) => getFPool(c, p.poolId)));
|
|
1486
1507
|
const authorities = await Promise.all(
|
|
1487
|
-
|
|
1488
|
-
c.public.readContract({ address:
|
|
1508
|
+
states.map((s) =>
|
|
1509
|
+
c.public.readContract({ address: s.policy, abi: fPolicyBaseAbi, functionName: "authority", args: [s.poolId] } as never) as Promise<Address>,
|
|
1489
1510
|
),
|
|
1490
1511
|
);
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1512
|
+
const out: FPoolControlled[] = [];
|
|
1513
|
+
for (let i = 0; i < pools.length; ++i) {
|
|
1514
|
+
if (authorities[i]!.toLowerCase() !== who.toLowerCase()) continue;
|
|
1515
|
+
const state = states[i]!;
|
|
1516
|
+
const roles = await getFPoolRoles(c, state.poolId, state);
|
|
1517
|
+
const rules = await getFPoolRules(c, state, roles);
|
|
1518
|
+
out.push({ pool: pools[i]!, roles, state, rules });
|
|
1519
|
+
}
|
|
1520
|
+
return out;
|
|
1500
1521
|
}
|
|
1501
1522
|
|
|
1502
1523
|
|