@logswap/sdk 0.5.50 → 0.5.51

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/fpool.d.ts CHANGED
@@ -110,6 +110,16 @@ export declare const fPolicyBaseAbi: readonly [{
110
110
  readonly type: "uint256";
111
111
  }];
112
112
  readonly stateMutability: "view";
113
+ }, {
114
+ readonly type: "function";
115
+ readonly inputs: readonly [];
116
+ readonly name: "kind";
117
+ readonly outputs: readonly [{
118
+ readonly name: "";
119
+ readonly internalType: "bytes32";
120
+ readonly type: "bytes32";
121
+ }];
122
+ readonly stateMutability: "pure";
113
123
  }, {
114
124
  readonly type: "function";
115
125
  readonly inputs: readonly [];
@@ -195,6 +205,20 @@ export declare const fPolicyBaseAbi: readonly [{
195
205
  readonly type: "uint256";
196
206
  }];
197
207
  readonly stateMutability: "view";
208
+ }, {
209
+ readonly type: "function";
210
+ readonly inputs: readonly [{
211
+ readonly name: "";
212
+ readonly internalType: "bytes32";
213
+ readonly type: "bytes32";
214
+ }];
215
+ readonly name: "nameOf";
216
+ readonly outputs: readonly [{
217
+ readonly name: "";
218
+ readonly internalType: "bytes32";
219
+ readonly type: "bytes32";
220
+ }];
221
+ readonly stateMutability: "view";
198
222
  }, {
199
223
  readonly type: "function";
200
224
  readonly inputs: readonly [{
@@ -276,10 +300,6 @@ export declare const fPolicyBaseAbi: readonly [{
276
300
  readonly name: "phi";
277
301
  readonly internalType: "uint256";
278
302
  readonly type: "uint256";
279
- }, {
280
- readonly name: "kind";
281
- readonly internalType: "enum Kind";
282
- readonly type: "uint8";
283
303
  }, {
284
304
  readonly name: "policy";
285
305
  readonly internalType: "address";
@@ -415,6 +435,30 @@ export declare const fPolicyBaseAbi: readonly [{
415
435
  readonly name: "proposeAuthority";
416
436
  readonly outputs: readonly [];
417
437
  readonly stateMutability: "nonpayable";
438
+ }, {
439
+ readonly type: "function";
440
+ readonly inputs: readonly [];
441
+ readonly name: "quoteCurated";
442
+ readonly outputs: readonly [{
443
+ readonly name: "";
444
+ readonly internalType: "bool";
445
+ readonly type: "bool";
446
+ }];
447
+ readonly stateMutability: "view";
448
+ }, {
449
+ readonly type: "function";
450
+ readonly inputs: readonly [{
451
+ readonly name: "";
452
+ readonly internalType: "address";
453
+ readonly type: "address";
454
+ }];
455
+ readonly name: "quoteListed";
456
+ readonly outputs: readonly [{
457
+ readonly name: "";
458
+ readonly internalType: "bool";
459
+ readonly type: "bool";
460
+ }];
461
+ readonly stateMutability: "view";
418
462
  }, {
419
463
  readonly type: "function";
420
464
  readonly inputs: readonly [{
@@ -425,6 +469,44 @@ export declare const fPolicyBaseAbi: readonly [{
425
469
  readonly name: "setHarvestCut";
426
470
  readonly outputs: readonly [];
427
471
  readonly stateMutability: "nonpayable";
472
+ }, {
473
+ readonly type: "function";
474
+ readonly inputs: readonly [{
475
+ readonly name: "poolId";
476
+ readonly internalType: "bytes32";
477
+ readonly type: "bytes32";
478
+ }, {
479
+ readonly name: "name_";
480
+ readonly internalType: "bytes32";
481
+ readonly type: "bytes32";
482
+ }];
483
+ readonly name: "setName";
484
+ readonly outputs: readonly [];
485
+ readonly stateMutability: "nonpayable";
486
+ }, {
487
+ readonly type: "function";
488
+ readonly inputs: readonly [{
489
+ readonly name: "curated";
490
+ readonly internalType: "bool";
491
+ readonly type: "bool";
492
+ }];
493
+ readonly name: "setQuoteCurated";
494
+ readonly outputs: readonly [];
495
+ readonly stateMutability: "nonpayable";
496
+ }, {
497
+ readonly type: "function";
498
+ readonly inputs: readonly [{
499
+ readonly name: "quote";
500
+ readonly internalType: "address";
501
+ readonly type: "address";
502
+ }, {
503
+ readonly name: "listed";
504
+ readonly internalType: "bool";
505
+ readonly type: "bool";
506
+ }];
507
+ readonly name: "setQuoteListed";
508
+ readonly outputs: readonly [];
509
+ readonly stateMutability: "nonpayable";
428
510
  }, {
429
511
  readonly type: "function";
430
512
  readonly inputs: readonly [{
@@ -489,6 +571,46 @@ export declare const fPolicyBaseAbi: readonly [{
489
571
  readonly indexed: false;
490
572
  }];
491
573
  readonly name: "HarvestCutSet";
574
+ }, {
575
+ readonly type: "event";
576
+ readonly anonymous: false;
577
+ readonly inputs: readonly [{
578
+ readonly name: "poolId";
579
+ readonly internalType: "bytes32";
580
+ readonly type: "bytes32";
581
+ readonly indexed: true;
582
+ }, {
583
+ readonly name: "name";
584
+ readonly internalType: "bytes32";
585
+ readonly type: "bytes32";
586
+ readonly indexed: false;
587
+ }];
588
+ readonly name: "NameSet";
589
+ }, {
590
+ readonly type: "event";
591
+ readonly anonymous: false;
592
+ readonly inputs: readonly [{
593
+ readonly name: "curated";
594
+ readonly internalType: "bool";
595
+ readonly type: "bool";
596
+ readonly indexed: false;
597
+ }];
598
+ readonly name: "QuoteCuratedSet";
599
+ }, {
600
+ readonly type: "event";
601
+ readonly anonymous: false;
602
+ readonly inputs: readonly [{
603
+ readonly name: "quote";
604
+ readonly internalType: "address";
605
+ readonly type: "address";
606
+ readonly indexed: true;
607
+ }, {
608
+ readonly name: "listed";
609
+ readonly internalType: "bool";
610
+ readonly type: "bool";
611
+ readonly indexed: false;
612
+ }];
613
+ readonly name: "QuoteListed";
492
614
  }, {
493
615
  readonly type: "event";
494
616
  readonly anonymous: false;
@@ -504,10 +626,18 @@ export declare const fPolicyBaseAbi: readonly [{
504
626
  readonly indexed: false;
505
627
  }];
506
628
  readonly name: "RulesSet";
629
+ }, {
630
+ readonly type: "error";
631
+ readonly inputs: readonly [];
632
+ readonly name: "BadFee";
507
633
  }, {
508
634
  readonly type: "error";
509
635
  readonly inputs: readonly [];
510
636
  readonly name: "BadRate";
637
+ }, {
638
+ readonly type: "error";
639
+ readonly inputs: readonly [];
640
+ readonly name: "NoCreator";
511
641
  }, {
512
642
  readonly type: "error";
513
643
  readonly inputs: readonly [];
@@ -520,6 +650,22 @@ export declare const fPolicyBaseAbi: readonly [{
520
650
  readonly type: "error";
521
651
  readonly inputs: readonly [];
522
652
  readonly name: "NotManager";
653
+ }, {
654
+ readonly type: "error";
655
+ readonly inputs: readonly [];
656
+ readonly name: "NotRegistry";
657
+ }, {
658
+ readonly type: "error";
659
+ readonly inputs: readonly [];
660
+ readonly name: "OneBase";
661
+ }, {
662
+ readonly type: "error";
663
+ readonly inputs: readonly [{
664
+ readonly name: "quote";
665
+ readonly internalType: "address";
666
+ readonly type: "address";
667
+ }];
668
+ readonly name: "QuoteNotListed";
523
669
  }, {
524
670
  readonly type: "error";
525
671
  readonly inputs: readonly [];
@@ -565,11 +711,11 @@ export interface FPoolState {
565
711
  policy: Address;
566
712
  /** Whether the policy asked to be consulted on swaps ({@link ASK_SWAP}) and mints ({@link ASK_MINT}) — the desk's policy does, no other. */
567
713
  asks: number;
568
- /** The sponsor's own label for this pool, mutable and never identity. "" when unnamed. */
714
+ /** The sponsor's own label for this pool — the policy's word (decisions 049), mutable and never identity. "" when unnamed. */
569
715
  name: string;
570
716
  /** The block of the last harvest / composition action: no swap runs in it. */
571
717
  restructureBlock: number;
572
- /** The rung — see {@link FPoolKind}. */
718
+ /** What the pool is — its POLICY's self-description (decisions 049); see {@link FPoolKind}. */
573
719
  kind: FPoolKind;
574
720
  /** False before the first seed — and between a retire and the next one (decisions 032). */
575
721
  seeded: boolean;
@@ -586,25 +732,27 @@ export interface FPoolState {
586
732
  /** Read a basket pool whole. Batched — viem multicalls these when the transport allows. */
587
733
  export declare function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolState>;
588
734
  /**
589
- * The kind of pool (decisions 036, 038, 044) — what the manager promises structurally, whatever
590
- * the pool's policy answers. `public`: the protocol's own pool — its policy requires the collector as
591
- * creator; no gate, no operator. `private`, the desk: the one kind whose policy may gate swaps and
592
- * mints, with an operator that reshapes the legs between generations. `pol`, a treasury's pool
593
- * or a basket: composition and access fixed at birth. `pad`, a launch: a POL whose harvest is
594
- * income only whatever its policy says and whose seed the contract minted to 0xdead — one asset,
595
- * open to all. private → pol → pad is the ladder of rigidity; public is a pol held by the
596
- * protocol. Every rate, role and gate is the policy's.
735
+ * The kind of pool — the POLICY's self-description (decisions 049: the manager knows no kind; the
736
+ * policy the key names is the kind, and what it promises is its code). `public`: the protocol's
737
+ * own pool — its policy requires the collector as creator; no gate, no operator. `private`, the
738
+ * desk: the one whose policy may gate swaps and mints, with an operator that reshapes the legs
739
+ * between generations. `pol`, a treasury's pool, one base: composition and access fixed at
740
+ * birth. `pad`, a launch, one base: its policy answers income only at every harvest and declared
741
+ * its seed the pool's at birth (`SEED_TO_DEAD`) — open to all. private → pol → pad is the ladder
742
+ * of rigidity; public is a pol held by the protocol. Every rate, role and gate is the policy's.
597
743
  */
598
744
  export type FPoolKind = "public" | "private" | "pol" | "pad";
599
- /** The key's enum values. */
600
- export declare const F_KIND: {
601
- readonly public: 0;
602
- readonly private: 1;
603
- readonly pol: 2;
604
- readonly pad: 3;
605
- };
606
- export declare function fPoolKindOf(n: number | bigint): FPoolKind;
607
- /** The deployment's policy for a kind (decisions 044): what a key of that kind names. */
745
+ /** The policy's birth-time declaration that the seed's shares are the pool's (a pad's), in `asks`. */
746
+ export declare const SEED_TO_DEAD = 4;
747
+ /**
748
+ * What a policy IS — its `kind()` tag, read once per policy address and cached for the client's
749
+ * chain: a pool's kind is its policy's word (decisions 049), never the manager's. An unknown tag
750
+ * (a policy that is not one of the protocol's four shapes) throws; the app has no screen for it.
751
+ */
752
+ export declare function fPoolKindOfPolicy(c: LogswapClient, policy: Address): Promise<FPoolKind>;
753
+ /** The pool's label, as its policy holds it (decisions 049). "" when unnamed. */
754
+ export declare function fPoolNameOf(c: LogswapClient, poolId: Hex, policy?: Address): Promise<string>;
755
+ /** The deployment's policy for a kind (decisions 044, 049): the protocol's policy that IS that kind. */
608
756
  export declare function fPoolPolicyFor(c: LogswapClient, kind: FPoolKind): Address;
609
757
  /** The policy a pool named in its key — one read; {@link getFPool} carries it too. */
610
758
  export declare function fPoolPolicyOf(c: LogswapClient, poolId: Hex): Promise<Address>;
@@ -875,12 +1023,16 @@ export interface FPoolCreateArgs {
875
1023
  weights: bigint[];
876
1024
  /** Fixed fee, WAD. The base-for-base fee is pinned at 2φ on-chain. */
877
1025
  phi: bigint;
878
- /** The rung (decisions 036) — see {@link FPoolKind}. In the key: the pool's identity, never changed after. */
1026
+ /**
1027
+ * Which of the protocol's four the pool is — see {@link FPoolKind}. NOT a key field (decisions
1028
+ * 049: the manager knows no kind): it selects the deployment's policy of that kind when `policy`
1029
+ * is not named ({@link fPoolPolicyFor}), and it is what the policy will say it is.
1030
+ */
879
1031
  kind: FPoolKind;
880
1032
  /**
881
- * The pool's policy (decisions 041, 044): the contract the key names, approved by the protocol
882
- * for the kind. Defaults to the deployment's policy for `kind` ({@link fPoolPolicyFor}) — the one
883
- * every protocol pool names.
1033
+ * The pool's policy (decisions 041, 044, 049): the contract the key names, approved by the
1034
+ * registry, and the pool's kind. Defaults to the deployment's policy for `kind`
1035
+ * ({@link fPoolPolicyFor}) — the one every protocol pool names.
884
1036
  */
885
1037
  policy?: Address;
886
1038
  /** Who is born holding the pool: immutable identity, the pool's first authority (the policy records it). */
@@ -889,7 +1041,7 @@ export interface FPoolCreateArgs {
889
1041
  * The differentiator, and nothing else. Identity is the key's hash, so one sponsor cannot run
890
1042
  * two pools of the same shape without varying it — the second `initialize` would land on the
891
1043
  * first pool's id. Defaults to zero, which is the first book of any shape. A pool's NAME is not
892
- * this: names are mutable state (`fPoolSetName`), so a rename forks nothing.
1044
+ * this: names are the policy's mutable state (`fPoolSetName`), so a rename forks nothing.
893
1045
  */
894
1046
  salt?: Hex;
895
1047
  account: Address;
@@ -902,13 +1054,12 @@ export declare function sortFPoolLegs<T>(bases: Address[], ...companions: T[][])
902
1054
  bases: Address[];
903
1055
  companions: T[][];
904
1056
  };
905
- /** The key as the manager hashes it: legs sorted, the kind's policy filled in when none is named. */
1057
+ /** The key as the manager hashes it: legs sorted, the kind's policy filled in when none is named; no kind in it (049). */
906
1058
  export declare function fPoolKeyOf(c: LogswapClient, a: Omit<FPoolCreateArgs, "account">): {
907
1059
  quote: `0x${string}`;
908
1060
  bases: `0x${string}`[];
909
1061
  weights: bigint[];
910
1062
  phi: bigint;
911
- kind: 0 | 1 | 3 | 2;
912
1063
  policy: `0x${string}`;
913
1064
  creator: `0x${string}`;
914
1065
  salt: `0x${string}`;
@@ -1038,7 +1189,7 @@ export interface FPoolLaunchArgs extends Omit<FPoolCreateArgs, "account"> {
1038
1189
  amountIn: bigint;
1039
1190
  minOut?: bigint;
1040
1191
  };
1041
- /** The pool's label, set in the batch (≤ 31 bytes of UTF-8). */
1192
+ /** The pool's label (≤ 31 bytes of UTF-8) — the policy's word (049), written right after the batch by {@link fPoolLaunch}; not in the batch. */
1042
1193
  name?: string;
1043
1194
  /**
1044
1195
  * The pool already exists (a previous launch got as far as `initialize` and no further — a seed
@@ -1152,23 +1303,27 @@ export declare function fPoolIsMinter(c: LogswapClient, poolId: Hex, who: Addres
1152
1303
  export declare function fPoolIsTaker(c: LogswapClient, poolId: Hex, who: Address, policy?: Address): Promise<boolean>;
1153
1304
  /** May swap: a minter or a taker (consulted only while the swap gate is on). */
1154
1305
  export declare function fPoolIsAllowed(c: LogswapClient, poolId: Hex, who: Address, policy?: Address): Promise<boolean>;
1155
- /** Label the pool — the sponsor's own words, mutable, never identity. At most 31 bytes of UTF-8. */
1306
+ /** Label the pool — the authority's own words on the pool's POLICY (decisions 049), mutable, never identity. At most 31 bytes of UTF-8. */
1156
1307
  export declare function fPoolSetName(c: LogswapClient, a: {
1157
1308
  poolId: Hex;
1158
1309
  name: string;
1159
1310
  account: Address;
1311
+ policy?: Address;
1160
1312
  }): Promise<`0x${string}`>;
1161
1313
  /**
1162
- * What the PROTOCOL says an address is — "Keyrock". Only `feeCollector` may write it, which is
1163
- * what makes it an attestation rather than a claim anyone could make about themselves.
1314
+ * What the PROTOCOL says an address is — "Keyrock" — on the REGISTRY (decisions 049). Only its
1315
+ * owner, the LOG authority, may write it, which is what makes it an attestation rather than a
1316
+ * claim anyone could make about themselves.
1164
1317
  */
1165
1318
  export declare function fPoolSetSponsorName(c: LogswapClient, a: {
1166
1319
  who: Address;
1167
1320
  name: string;
1168
1321
  account: Address;
1169
1322
  }): Promise<`0x${string}`>;
1170
- /** The protocol's attestation for an address, or "" when unattested — which most addresses are. */
1323
+ /** The protocol's attestation for an address, or "" when unattested — which most addresses are, and every address on a deployment with no registry. */
1171
1324
  export declare function fPoolSponsorName(c: LogswapClient, who: Address): Promise<string>;
1325
+ /** The registry the manager asks at every birth — `addresses.policyRegistry`, else the manager's word; zero on a bare deployment. */
1326
+ export declare function fPoolRegistryOf(c: LogswapClient): Promise<Address>;
1172
1327
  /** Who runs the pool (decisions 037): the appointed operator, or the authority until one is. */
1173
1328
  export declare function fPoolOperatorOf(s: Pick<FPoolRoles, "authority" | "operator">): Address;
1174
1329
  /**
@@ -1240,9 +1395,10 @@ export interface DiscoveredFPool {
1240
1395
  shape: FPoolShape;
1241
1396
  }
1242
1397
  /**
1243
- * Every F pool ever created, from `Initialize` logs alone. Possible only because the event
1244
- * carries the full key preimage (bases, weights, phi, pad) — the poolId is a hash and could
1245
- * never be inverted; contracts PR #17 exists for exactly this call.
1398
+ * Every F pool ever created, from `Initialize` logs alone — plus one `kind()` read per distinct
1399
+ * policy, cached. Possible only because the event carries the full key preimage (bases,
1400
+ * weights, phi, policy) — the poolId is a hash and could never be inverted; contracts PR #17
1401
+ * exists for exactly this call.
1246
1402
  */
1247
1403
  export declare function discoverFPools(c: LogswapClient, opts?: {
1248
1404
  fromBlock?: bigint;
package/dist/fpool.js CHANGED
@@ -30,7 +30,7 @@
30
30
  * `addresses.router`.
31
31
  */
32
32
  import { encodeFunctionData, toFunctionSelector } from "viem";
33
- import { fPoolManagerAbi, logswapRouterAbi, padPolicyAbi, polPolicyAbi, privatePolicyAbi, publicPolicyAbi } from "./generated.js";
33
+ import { fPoolManagerAbi, logswapRouterAbi, padPolicyAbi, polPolicyAbi, policyRegistryAbi, privatePolicyAbi, publicPolicyAbi } from "./generated.js";
34
34
  /**
35
35
  * One contract, one ABI (decisions 039, F version 12): `harvest`, `claim`, `retire`, `regenerate`,
36
36
  * `setLegs`, the names, the fee parameters are `FPoolManager`'s own code. The roles left it for
@@ -61,7 +61,8 @@ export async function getFPool(c, poolId) {
61
61
  args,
62
62
  });
63
63
  // `getPool` returns the whole scalar struct in one call — the singleton's shape makes what used
64
- // to be a dozen getters a single read. No role in it since F version 15: those are the policy's.
64
+ // to be a dozen getters a single read. No role in it since F version 15, no kind and no name
65
+ // since 18: those are the policy's.
65
66
  const p = await rd("getPool", [poolId]);
66
67
  // A pool that was never created reads as an all-zero struct rather than reverting, so the
67
68
  // absence has to be named here or every caller mistakes "no such pool" for "a pool holding
@@ -72,12 +73,14 @@ export async function getFPool(c, poolId) {
72
73
  throw new Error(`logswap: no F pool with id ${poolId}`);
73
74
  const n = Number(p.n);
74
75
  const idx = Array.from({ length: n }, (_, i) => BigInt(i));
75
- const [theta, compositeX, legs] = await Promise.all([
76
+ const [theta, compositeX, legs, kind, name] = await Promise.all([
76
77
  // before the seed there is no L and no floor: θ is X by convention (the manager says so since
77
78
  // bd3dd87's successor; older deployments revert with DivWadFailed, so do not ask them)
78
79
  p.L > 0n ? rd("theta", [poolId]) : rd("compositeX", [poolId]),
79
80
  rd("compositeX", [poolId]),
80
81
  Promise.all(idx.map((i) => rd("legOf", [poolId, i]))),
82
+ fPoolKindOfPolicy(c, p.policy),
83
+ fPoolNameOf(c, poolId, p.policy),
81
84
  ]);
82
85
  const bases = legs.map((l) => l[0]);
83
86
  const weights = legs.map((l) => l[1]);
@@ -100,25 +103,46 @@ export async function getFPool(c, poolId) {
100
103
  bigSigma,
101
104
  policy,
102
105
  asks: Number(p.asks),
103
- name: bytes32ToText(p.name),
106
+ name,
104
107
  restructureBlock: Number(restructureBlock),
105
- kind: fPoolKindOf(p.kind),
108
+ kind,
106
109
  seeded,
107
110
  gen: Number(gen),
108
111
  totalSupply,
109
112
  reserves,
110
113
  };
111
114
  }
112
- /** The key's enum values. */
113
- export const F_KIND = { public: 0, private: 1, pol: 2, pad: 3 };
114
115
  const F_KIND_NAMES = ["public", "private", "pol", "pad"];
115
- export function fPoolKindOf(n) {
116
- const k = F_KIND_NAMES[Number(n)];
117
- if (!k)
118
- throw new Error(`logswap: unknown pool kind ${n}`);
119
- return k;
116
+ /** The policy's birth-time declaration that the seed's shares are the pool's (a pad's), in `asks`. */
117
+ export const SEED_TO_DEAD = 4;
118
+ const kindCache = new Map();
119
+ /**
120
+ * What a policy IS — its `kind()` tag, read once per policy address and cached for the client's
121
+ * chain: a pool's kind is its policy's word (decisions 049), never the manager's. An unknown tag
122
+ * (a policy that is not one of the protocol's four shapes) throws; the app has no screen for it.
123
+ */
124
+ export function fPoolKindOfPolicy(c, policy) {
125
+ const key = `${c.public.chain?.id ?? 0}:${policy.toLowerCase()}`;
126
+ let hit = kindCache.get(key);
127
+ if (!hit) {
128
+ hit = c.public.readContract({ address: policy, abi: fPolicyBaseAbi, functionName: "kind" }).then((word) => {
129
+ const tag = bytes32ToText(word);
130
+ if (!F_KIND_NAMES.includes(tag))
131
+ throw new Error(`logswap: policy ${policy} says it is "${tag}", which is no kind this SDK knows`);
132
+ return tag;
133
+ });
134
+ kindCache.set(key, hit);
135
+ hit.catch(() => kindCache.delete(key)); // a failed read is not a fact
136
+ }
137
+ return hit;
120
138
  }
121
- /** The deployment's policy for a kind (decisions 044): what a key of that kind names. */
139
+ /** The pool's label, as its policy holds it (decisions 049). "" when unnamed. */
140
+ export async function fPoolNameOf(c, poolId, policy) {
141
+ const p = policy ?? (await fPoolPolicyOf(c, poolId));
142
+ const word = (await c.public.readContract({ address: p, abi: fPolicyBaseAbi, functionName: "nameOf", args: [poolId] }));
143
+ return bytes32ToText(word);
144
+ }
145
+ /** The deployment's policy for a kind (decisions 044, 049): the protocol's policy that IS that kind. */
122
146
  export function fPoolPolicyFor(c, kind) {
123
147
  const a = c.addresses;
124
148
  const policy = kind === "public" ? a.publicPolicy : kind === "private" ? a.privatePolicy : kind === "pol" ? a.polPolicy : a.padPolicy;
@@ -541,8 +565,8 @@ export var FPoolQuoteKind;
541
565
  export async function fPoolQuoteSwap(c, a) {
542
566
  try {
543
567
  await c.public.simulateContract({
544
- address: c.addresses.fPoolManager,
545
- abi: fPoolManagerAbi,
568
+ address: c.addresses.router,
569
+ abi: logswapRouterAbi,
546
570
  functionName: "quoteSwap",
547
571
  // the taker matters only on a gated pool: the connected account, or the zero address
548
572
  args: [a.poolId, a.kind, BigInt(a.j), BigInt(a.k ?? 0), a.amountIn, a.taker ?? c.wallet?.account?.address ?? ZERO_ADDRESS],
@@ -606,7 +630,7 @@ export function sortFPoolLegs(bases, ...companions) {
606
630
  const idx = bases.map((_, i) => i).sort((a, b) => (bases[a].toLowerCase() < bases[b].toLowerCase() ? -1 : 1));
607
631
  return { bases: idx.map((i) => bases[i]), companions: companions.map((arr) => idx.map((i) => arr[i])) };
608
632
  }
609
- /** The key as the manager hashes it: legs sorted, the kind's policy filled in when none is named. */
633
+ /** The key as the manager hashes it: legs sorted, the kind's policy filled in when none is named; no kind in it (049). */
610
634
  export function fPoolKeyOf(c, a) {
611
635
  const { bases, companions } = sortFPoolLegs(a.bases, a.weights);
612
636
  return {
@@ -614,7 +638,6 @@ export function fPoolKeyOf(c, a) {
614
638
  bases,
615
639
  weights: companions[0],
616
640
  phi: a.phi,
617
- kind: F_KIND[a.kind],
618
641
  policy: a.policy ?? fPoolPolicyFor(c, a.kind),
619
642
  creator: a.creator,
620
643
  salt: a.salt ?? ZERO_SALT,
@@ -769,7 +792,7 @@ export function fPoolLaunchCalls(poolId, a) {
769
792
  const { bases, companions } = sortFPoolLegs(a.bases, a.weights, given);
770
793
  if (!a.policy)
771
794
  throw new Error("logswap: fPoolLaunchCalls needs the key's policy — fPoolLaunch fills it from the deployment");
772
- const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi, kind: F_KIND[a.kind], policy: a.policy, creator: a.creator, salt: a.salt ?? ZERO_SALT };
795
+ const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi, policy: a.policy, creator: a.creator, salt: a.salt ?? ZERO_SALT };
773
796
  const enc = (functionName, args) => encodeFunctionData({ abi: fPoolManagerAbi, functionName, args });
774
797
  const calls = [];
775
798
  if (!a.initialized)
@@ -783,10 +806,9 @@ export function fPoolLaunchCalls(poolId, a) {
783
806
  throw new Error(`logswap: openBuy.j = ${a.openBuy.j} is not a leg`);
784
807
  calls.push(enc("swapQuoteIn", [poolId, BigInt(j), a.openBuy.amountIn, a.openBuy.minOut ?? 0n, a.account]));
785
808
  }
786
- if (a.name)
787
- calls.push(enc("setName", [poolId, textToBytes32(a.name)]));
788
- // the desk's gates and list are the POLICY's (decisions 044), not the manager's: they cannot ride
789
- // in this batch — `fPoolDeskOpening` sends them right after, as the same creator
809
+ // the name, the desk's gates and its list are the POLICY's (decisions 044, 049), not the
810
+ // manager's: they cannot ride in this batch — `fPoolLaunch` and `fPoolDeskOpening` send them
811
+ // right after, as the same creator
790
812
  calls.push(...(a.extra ?? []));
791
813
  return calls;
792
814
  }
@@ -821,8 +843,11 @@ export async function fPoolDeskOpening(c, a) {
821
843
  */
822
844
  export async function fPoolLaunch(c, a) {
823
845
  const poolId = await fPoolIdOf(c, a);
824
- const calls = fPoolLaunchCalls(poolId, { ...a, policy: a.policy ?? fPoolPolicyFor(c, a.kind) });
846
+ const policy = a.policy ?? fPoolPolicyFor(c, a.kind);
847
+ const calls = fPoolLaunchCalls(poolId, { ...a, policy });
825
848
  const hash = await writeFPool0(c, "multicall", [calls], a.account);
849
+ if (a.name)
850
+ await fPoolSetName(c, { poolId, name: a.name, account: a.account, policy });
826
851
  return { hash, poolId };
827
852
  }
828
853
  // ─── the roles, on the policy (decisions 044) ─────────────────────────────────────────────
@@ -892,35 +917,47 @@ export async function fPoolIsTaker(c, poolId, who, policy) {
892
917
  export async function fPoolIsAllowed(c, poolId, who, policy) {
893
918
  return readDesk(c, poolId, who, "isAllowed", policy);
894
919
  }
895
- /** Label the pool — the sponsor's own words, mutable, never identity. At most 31 bytes of UTF-8. */
920
+ /** Label the pool — the authority's own words on the pool's POLICY (decisions 049), mutable, never identity. At most 31 bytes of UTF-8. */
896
921
  export async function fPoolSetName(c, a) {
897
- return writeFPool(c, a.poolId, "setName", [textToBytes32(a.name)], a.account);
922
+ return writePolicy(c, fPolicyBaseAbi, a, "setName", [textToBytes32(a.name)]);
898
923
  }
899
924
  /**
900
- * What the PROTOCOL says an address is — "Keyrock". Only `feeCollector` may write it, which is
901
- * what makes it an attestation rather than a claim anyone could make about themselves.
925
+ * What the PROTOCOL says an address is — "Keyrock" — on the REGISTRY (decisions 049). Only its
926
+ * owner, the LOG authority, may write it, which is what makes it an attestation rather than a
927
+ * claim anyone could make about themselves.
902
928
  */
903
929
  export async function fPoolSetSponsorName(c, a) {
904
930
  const wallet = requireWallet(c);
931
+ const registry = await registryAddress(c);
905
932
  const { request } = await c.public.simulateContract({
906
- address: c.addresses.fPoolManager,
907
- abi: fPoolManagerAbi,
933
+ address: registry,
934
+ abi: policyRegistryAbi,
908
935
  functionName: "setSponsorName",
909
936
  args: [a.who, textToBytes32(a.name)],
910
937
  account: a.account,
911
938
  });
912
939
  return wallet.writeContract(request);
913
940
  }
914
- /** The protocol's attestation for an address, or "" when unattested — which most addresses are. */
941
+ /** The protocol's attestation for an address, or "" when unattested — which most addresses are, and every address on a deployment with no registry. */
915
942
  export async function fPoolSponsorName(c, who) {
916
- const word = (await c.public.readContract({
917
- address: c.addresses.fPoolManager,
918
- abi: fPoolManagerAbi,
919
- functionName: "sponsorName",
920
- args: [who],
921
- }));
943
+ const registry = c.addresses.policyRegistry ?? (await fPoolRegistryOf(c));
944
+ if (registry === ZERO_ADDRESS)
945
+ return "";
946
+ const word = (await c.public.readContract({ address: registry, abi: policyRegistryAbi, functionName: "sponsorName", args: [who] }));
922
947
  return bytes32ToText(word);
923
948
  }
949
+ /** The registry the manager asks at every birth — `addresses.policyRegistry`, else the manager's word; zero on a bare deployment. */
950
+ export async function fPoolRegistryOf(c) {
951
+ if (c.addresses.policyRegistry)
952
+ return c.addresses.policyRegistry;
953
+ return (await c.public.readContract({ address: c.addresses.fPoolManager, abi: fPoolManagerAbi, functionName: "registry" }));
954
+ }
955
+ async function registryAddress(c) {
956
+ const registry = await fPoolRegistryOf(c);
957
+ if (registry === ZERO_ADDRESS)
958
+ throw new Error("logswap: this deployment carries no policy registry");
959
+ return registry;
960
+ }
924
961
  /** Who runs the pool (decisions 037): the appointed operator, or the authority until one is. */
925
962
  export function fPoolOperatorOf(s) {
926
963
  return s.operator === ZERO_ADDRESS ? s.authority : s.operator;
@@ -966,9 +1003,10 @@ export async function fPoolTransferShares(c, a) {
966
1003
  return wallet.writeContract(request);
967
1004
  }
968
1005
  /**
969
- * Every F pool ever created, from `Initialize` logs alone. Possible only because the event
970
- * carries the full key preimage (bases, weights, phi, pad) — the poolId is a hash and could
971
- * never be inverted; contracts PR #17 exists for exactly this call.
1006
+ * Every F pool ever created, from `Initialize` logs alone — plus one `kind()` read per distinct
1007
+ * policy, cached. Possible only because the event carries the full key preimage (bases,
1008
+ * weights, phi, policy) — the poolId is a hash and could never be inverted; contracts PR #17
1009
+ * exists for exactly this call.
972
1010
  */
973
1011
  export async function discoverFPools(c, opts = {}) {
974
1012
  const ev = fPoolManagerAbi.find((x) => x.type === "event" && x.name === "Initialize");
@@ -991,24 +1029,25 @@ export async function discoverFPools(c, opts = {}) {
991
1029
  const a = l.args;
992
1030
  q0Of.set(a.poolId.toLowerCase(), a.Q0);
993
1031
  }
994
- return logs.map((l) => {
1032
+ return Promise.all(logs.map(async (l) => {
995
1033
  const a = l.args;
996
1034
  const q0 = q0Of.get(a.poolId.toLowerCase());
1035
+ const kind = await fPoolKindOfPolicy(c, a.policy); // one read per distinct policy, cached
997
1036
  return {
998
1037
  poolId: a.poolId,
999
1038
  quote: a.quote,
1000
1039
  bases: [...a.bases],
1001
1040
  weights: [...a.weights],
1002
1041
  phi: a.phi,
1003
- kind: fPoolKindOf(a.kind),
1042
+ kind,
1004
1043
  policy: a.policy,
1005
1044
  creator: a.creator,
1006
1045
  block: l.blockNumber ?? 0n,
1007
1046
  seeded: q0 !== undefined,
1008
1047
  q0: q0 ?? 0n,
1009
- shape: a.kind === F_KIND.pad ? "launch" : "basket", // the kind, not n = 1: a mono POL is a pool (decisions 036)
1048
+ shape: kind === "pad" ? "launch" : "basket", // the policy's word, not n = 1: a mono POL is a pool (decisions 036, 049)
1010
1049
  };
1011
- });
1050
+ }));
1012
1051
  }
1013
1052
  /** The policy's terms for one pool, by its kind. */
1014
1053
  export async function getFPoolRules(c, s, roles) {