@floorlaunchpad/sdk-evm 0.0.0-stage → 0.1.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.
Files changed (67) hide show
  1. package/LICENSE +61 -0
  2. package/README.md +154 -2
  3. package/dist/abi/floor.d.ts +1315 -0
  4. package/dist/abi/floor.d.ts.map +1 -0
  5. package/dist/abi/floor.js +154 -0
  6. package/dist/abi/floor.js.map +1 -0
  7. package/dist/abi/generated.d.ts +12824 -0
  8. package/dist/abi/generated.d.ts.map +1 -0
  9. package/dist/abi/generated.js +1264 -0
  10. package/dist/abi/generated.js.map +1 -0
  11. package/dist/abi/index.d.ts +2 -0
  12. package/dist/abi/index.d.ts.map +1 -0
  13. package/dist/abi/index.js +2 -0
  14. package/dist/abi/index.js.map +1 -0
  15. package/dist/adapter.d.ts +89 -0
  16. package/dist/adapter.d.ts.map +1 -0
  17. package/dist/adapter.js +250 -0
  18. package/dist/adapter.js.map +1 -0
  19. package/dist/deployments.d.ts +154 -0
  20. package/dist/deployments.d.ts.map +1 -0
  21. package/dist/deployments.js +368 -0
  22. package/dist/deployments.js.map +1 -0
  23. package/dist/errors.d.ts +56 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/errors.js +42 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/events.d.ts +45 -0
  28. package/dist/events.d.ts.map +1 -0
  29. package/dist/events.js +78 -0
  30. package/dist/events.js.map +1 -0
  31. package/dist/fees.d.ts +100 -0
  32. package/dist/fees.d.ts.map +1 -0
  33. package/dist/fees.js +156 -0
  34. package/dist/fees.js.map +1 -0
  35. package/dist/index.d.ts +18 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +18 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/pool.d.ts +63 -0
  40. package/dist/pool.d.ts.map +1 -0
  41. package/dist/pool.js +118 -0
  42. package/dist/pool.js.map +1 -0
  43. package/dist/reads.d.ts +107 -0
  44. package/dist/reads.d.ts.map +1 -0
  45. package/dist/reads.js +201 -0
  46. package/dist/reads.js.map +1 -0
  47. package/dist/router.d.ts +99 -0
  48. package/dist/router.d.ts.map +1 -0
  49. package/dist/router.js +132 -0
  50. package/dist/router.js.map +1 -0
  51. package/dist/sale.d.ts +79 -0
  52. package/dist/sale.d.ts.map +1 -0
  53. package/dist/sale.js +123 -0
  54. package/dist/sale.js.map +1 -0
  55. package/dist/send.d.ts +64 -0
  56. package/dist/send.d.ts.map +1 -0
  57. package/dist/send.js +137 -0
  58. package/dist/send.js.map +1 -0
  59. package/dist/simulate.d.ts +180 -0
  60. package/dist/simulate.d.ts.map +1 -0
  61. package/dist/simulate.js +270 -0
  62. package/dist/simulate.js.map +1 -0
  63. package/dist/trade.d.ts +140 -0
  64. package/dist/trade.d.ts.map +1 -0
  65. package/dist/trade.js +170 -0
  66. package/dist/trade.js.map +1 -0
  67. package/package.json +43 -4
package/dist/fees.d.ts ADDED
@@ -0,0 +1,100 @@
1
+ /**
2
+ * What a FLOOR trade costs, in integers — the contracts' own arithmetic, never a float.
3
+ *
4
+ * Mirrors `FloorHookMath.skimBps` and the hook engine's `_takeFees`, and `FloorLaunch`'s fee rounding.
5
+ *
6
+ * The trader's take on a POOL swap is five parts, listed whole or not at all:
7
+ * floor skim + creator fee + holder tax + FLOOR Platform fee — four percentages of the SAME quote leg, each rounded down and
8
+ * summed (`_takeFees`) — and the 0.25% LP fee, which the pool charges on what the hook leaves.
9
+ * A BONDING trade (before graduation) pays the SALE's FLOOR Platform fee and nothing else: there is no pool yet, so its skim,
10
+ * creator fee, holder tax and LP fee are zero, and are still listed (as 0) so the take is whole.
11
+ * ⛔ Every rate is READ per launch / per pool (each copied its rates at creation). Nothing here holds a rate.
12
+ * ⛔ The 2.5% `$FLOOR` cut is NOT a take: it is a split of the skim the trader already paid. It is never in a quote.
13
+ */
14
+ import type { FeePart } from '@floorlaunchpad/sdk';
15
+ /** `FloorPolicy.MAX_SALE_TEAM_FEE_BPS` — the most a sale's FLOOR Platform fee can be. */
16
+ export declare const MAX_SALE_TEAM_FEE_BPS = 100;
17
+ /** `FloorPolicy.MAX_POOL_TEAM_FEE_BPS` — the most a pool's FLOOR Platform fee can be. */
18
+ export declare const MAX_POOL_TEAM_FEE_BPS = 50;
19
+ /** `value` as a rate in [0, cap], or a throw naming `what` (`RateAboveCap` past the cap). */
20
+ export declare function rateWithinCap(value: number, cap: number, what: string): number;
21
+ /** `amount × bps / 10_000`, rounded DOWN — the one rounding the contracts use for the FLOOR Platform fee. */
22
+ export declare function teamFeeOf(amount: bigint, bps: number): bigint;
23
+ /** A sale buy's NET (what the walk runs on) out of the GROSS sent: `floor(gross × 10_000 / (10_000 + bps))`. */
24
+ export declare function saleNetOf(gross: bigint, bps: number): bigint;
25
+ /** The least gross whose net covers `spent`: `ceil(spent × (10_000 + bps) / 10_000)`. */
26
+ export declare function saleGrossFor(spent: bigint, bps: number): bigint;
27
+ /** A sell-back's fee and pay off its `payout` (what `sellBackQuote` gives under the contract version's rule): paid `payout − fee`. */
28
+ export declare function sellBackPayOf(payout: bigint, bps: number): {
29
+ fee: bigint;
30
+ paid: bigint;
31
+ };
32
+ /** A pool's own rates, in bps, as `poolState` stores them (copied once at registration, never moved). */
33
+ export interface PoolRates {
34
+ skimBuyFarBps: number;
35
+ skimSellFarBps: number;
36
+ skimBuyAtFloorBps: number;
37
+ skimSellAtFloorBps: number;
38
+ creatorBuyBps: number;
39
+ creatorSellBps: number;
40
+ holderBuyBps: number;
41
+ holderSellBps: number;
42
+ /** The pool's FLOOR Platform fee, checked against `MAX_POOL_TEAM_FEE_BPS`. */
43
+ teamFeeBps: number;
44
+ }
45
+ /**
46
+ * `FloorHookMath.skimBps`, statement for statement: the skim in whole bps at `distance` ticks from the band's DEAR edge
47
+ * (`dearEdge − current`, engine frame). A buy ramps from its at-floor rate at the bid to its far rate at the top of the
48
+ * ramp; a sell from its at-floor rate down to its far rate; a sell whose far rate is at or above its at-floor rate is flat.
49
+ */
50
+ export declare function skimBpsAt(side: 'buy' | 'sell', distance: number, r: Pick<PoolRates, 'skimBuyFarBps' | 'skimSellFarBps' | 'skimBuyAtFloorBps' | 'skimSellAtFloorBps'>): number;
51
+ /** `FloorPolicy.STAIR_GAP_SKIM_TICKS`: the gap (ticks) at and past which a buy's skim is scaled by the full multiplier. */
52
+ export declare const GAP_SKIM_TICKS = 5109;
53
+ /** `FloorPolicy.STAIR_GAP_SKIM_FROM_TICKS`: the gap (ticks) at and under which a buy's skim is not scaled. */
54
+ export declare const GAP_SKIM_FROM_TICKS = 2232;
55
+ /** `FloorPolicy.STAIR_GAP_SKIM_MULT_BPS`: the full multiplier, bps (1.5×). */
56
+ export declare const GAP_SKIM_MULT_BPS = 15000;
57
+ /** `FloorPolicy.STAIR_GAP_SKIM_MAX_BPS`: the cap on a scaled buy skim, bps. */
58
+ export declare const GAP_SKIM_MAX_BPS = 1500;
59
+ /** The pool's staircase cushion as `stairs()` answers it — the two fields the gap buy skim reads (engine-frame ticks). */
60
+ export interface CushionEdge {
61
+ /** The cushion's dear edge (its top in price), engine frame. */
62
+ cushionLower: number;
63
+ /** 0 when no cushion stands in the pool. */
64
+ cushionLiq: bigint;
65
+ }
66
+ /**
67
+ * `SingletonFloorEngine._gapSkim`, statement for statement: a BUY's floor skim `bps` (already ramped, `skimBpsAt`) scaled by
68
+ * how far the price stands above the cushion's top. `gap = cushionLower − current` (engine frame). At `gap ≥ 5,109` the
69
+ * multiplier is 1.5×; between 2,232 (exclusive) and 5,109 it rises linearly in ticks,
70
+ * `10_000 + 5_000 × (gap − 2,232) / (5,109 − 2,232)` (floored); at or under 2,232 the skim is returned untouched. A scaled
71
+ * skim is `floor(bps × m / 10_000)`, capped at 1,500. No cushion standing (`cushionLiq == 0`): untouched.
72
+ */
73
+ export declare function gapSkimBps(bps: number, cushion: CushionEdge, currentTick: number): number;
74
+ /** The hook's four takes off ONE quote leg, each `leg × bps / 10_000` rounded down (`_takeFees`). */
75
+ export declare function hookTakes(side: 'buy' | 'sell', leg: bigint, skimBps: number, r: PoolRates): {
76
+ floorSkim: bigint;
77
+ creator: bigint;
78
+ holder: bigint;
79
+ floorPlatform: bigint;
80
+ total: bigint;
81
+ };
82
+ /**
83
+ * A pool swap's five parts, in the QUOTE's smallest unit.
84
+ * - BUY (exact quote in, the leg is `amountIn`): the hook takes its four off the leg BEFORE the swap (`_beforeSwap`), at the
85
+ * PRE-swap tick; the LP fee is the pool's 0.25% of what is left (`ceil`, as v4's swap step rounds it).
86
+ * - SELL (exact tokens in, the leg is the swap's quote output): the hook takes its four AFTER the swap, off the leg; `amountOut`
87
+ * is the leg less them, so the leg is the least value whose remainder covers `amountOut`. The LP fee was charged on the
88
+ * TOKEN input and is stated in quote at the swap's own rate, `leg × fee / (1e6 − fee)` — an estimate.
89
+ * ⚠ A sell's skim is charged at the POST-swap tick (further up the ramp toward the floor); `skimBps` here is whatever the caller
90
+ * read. Pass the pre-trade figure and the skim part is a MINIMUM.
91
+ * A buy's `skimBps` is the figure the engine charges: on contracts with the gap buy skim, `gapSkimBps(skimBpsAt(...), ...)`.
92
+ */
93
+ export declare function poolFeeParts(side: 'buy' | 'sell', amountIn: bigint, amountOut: bigint, skimBps: number, r: PoolRates): FeePart[];
94
+ /** A bonding trade's take: the sale's FLOOR Platform fee, and the four pool parts at zero (there is no pool yet). */
95
+ export declare function bondingFeeParts(floorPlatform: bigint): FeePart[];
96
+ /** The five kinds an EVM quote lists, in order. A list missing any of them is refused (`assertWholeTake`). */
97
+ export declare const EVM_FEE_KINDS: readonly ["lp", "floorSkim", "creator", "holder", "floorPlatform"];
98
+ /** Throws unless `fees` names each of the five EVM parts exactly once — the whole take, or none of it. */
99
+ export declare function assertWholeTake(fees: readonly FeePart[]): void;
100
+ //# sourceMappingURL=fees.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../src/fees.ts"],"names":[],"mappings":"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"}
package/dist/fees.js ADDED
@@ -0,0 +1,156 @@
1
+ import { RateAboveCap } from './errors.js';
2
+ import { LP_FEE_PIPS, SKIM_RAMP_TICKS } from './pool.js';
3
+ /** `FloorPolicy.MAX_SALE_TEAM_FEE_BPS` — the most a sale's FLOOR Platform fee can be. */
4
+ export const MAX_SALE_TEAM_FEE_BPS = 100;
5
+ /** `FloorPolicy.MAX_POOL_TEAM_FEE_BPS` — the most a pool's FLOOR Platform fee can be. */
6
+ export const MAX_POOL_TEAM_FEE_BPS = 50;
7
+ /** `value` as a rate in [0, cap], or a throw naming `what` (`RateAboveCap` past the cap). */
8
+ export function rateWithinCap(value, cap, what) {
9
+ if (!Number.isInteger(value) || value < 0)
10
+ throw new RangeError(`${what}: ${String(value)} is not a rate`);
11
+ if (value > cap)
12
+ throw new RateAboveCap(what, value, cap);
13
+ return value;
14
+ }
15
+ const rateOf = (bps) => {
16
+ if (!Number.isInteger(bps) || bps < 0 || bps >= 10_000)
17
+ throw new RangeError(`the FLOOR Platform fee: ${bps} bps is not a rate in 0..9999`);
18
+ return BigInt(bps);
19
+ };
20
+ /** `amount × bps / 10_000`, rounded DOWN — the one rounding the contracts use for the FLOOR Platform fee. */
21
+ export function teamFeeOf(amount, bps) {
22
+ const b = rateOf(bps);
23
+ return amount <= 0n ? 0n : (amount * b) / 10000n;
24
+ }
25
+ /** A sale buy's NET (what the walk runs on) out of the GROSS sent: `floor(gross × 10_000 / (10_000 + bps))`. */
26
+ export function saleNetOf(gross, bps) {
27
+ const b = rateOf(bps);
28
+ return gross <= 0n ? 0n : (gross * 10000n) / (10000n + b);
29
+ }
30
+ /** The least gross whose net covers `spent`: `ceil(spent × (10_000 + bps) / 10_000)`. */
31
+ export function saleGrossFor(spent, bps) {
32
+ const n = spent * (10000n + rateOf(bps));
33
+ return n / 10000n + (n % 10000n === 0n ? 0n : 1n);
34
+ }
35
+ /** A sell-back's fee and pay off its `payout` (what `sellBackQuote` gives under the contract version's rule): paid `payout − fee`. */
36
+ export function sellBackPayOf(payout, bps) {
37
+ const fee = teamFeeOf(payout, bps);
38
+ return { fee, paid: payout - fee };
39
+ }
40
+ /**
41
+ * `FloorHookMath.skimBps`, statement for statement: the skim in whole bps at `distance` ticks from the band's DEAR edge
42
+ * (`dearEdge − current`, engine frame). A buy ramps from its at-floor rate at the bid to its far rate at the top of the
43
+ * ramp; a sell from its at-floor rate down to its far rate; a sell whose far rate is at or above its at-floor rate is flat.
44
+ */
45
+ export function skimBpsAt(side, distance, r) {
46
+ const ramp = SKIM_RAMP_TICKS;
47
+ let closeness = 0;
48
+ if (distance <= 0)
49
+ closeness = 10_000;
50
+ else if (distance < ramp)
51
+ closeness = 10_000 - Math.floor((distance * 10_000) / ramp);
52
+ if (side === 'buy') {
53
+ const far = r.skimBuyFarBps, at = r.skimBuyAtFloorBps;
54
+ if (far >= at)
55
+ return far - Math.floor(((far - at) * closeness) / 10_000);
56
+ return far + Math.floor(((at - far) * closeness) / 10_000);
57
+ }
58
+ const far = r.skimSellFarBps, at = r.skimSellAtFloorBps;
59
+ if (far >= at)
60
+ return far;
61
+ return far + Math.floor(((at - far) * closeness) / 10_000);
62
+ }
63
+ /** `FloorPolicy.STAIR_GAP_SKIM_TICKS`: the gap (ticks) at and past which a buy's skim is scaled by the full multiplier. */
64
+ export const GAP_SKIM_TICKS = 5_109;
65
+ /** `FloorPolicy.STAIR_GAP_SKIM_FROM_TICKS`: the gap (ticks) at and under which a buy's skim is not scaled. */
66
+ export const GAP_SKIM_FROM_TICKS = 2_232;
67
+ /** `FloorPolicy.STAIR_GAP_SKIM_MULT_BPS`: the full multiplier, bps (1.5×). */
68
+ export const GAP_SKIM_MULT_BPS = 15_000;
69
+ /** `FloorPolicy.STAIR_GAP_SKIM_MAX_BPS`: the cap on a scaled buy skim, bps. */
70
+ export const GAP_SKIM_MAX_BPS = 1_500;
71
+ /**
72
+ * `SingletonFloorEngine._gapSkim`, statement for statement: a BUY's floor skim `bps` (already ramped, `skimBpsAt`) scaled by
73
+ * how far the price stands above the cushion's top. `gap = cushionLower − current` (engine frame). At `gap ≥ 5,109` the
74
+ * multiplier is 1.5×; between 2,232 (exclusive) and 5,109 it rises linearly in ticks,
75
+ * `10_000 + 5_000 × (gap − 2,232) / (5,109 − 2,232)` (floored); at or under 2,232 the skim is returned untouched. A scaled
76
+ * skim is `floor(bps × m / 10_000)`, capped at 1,500. No cushion standing (`cushionLiq == 0`): untouched.
77
+ */
78
+ export function gapSkimBps(bps, cushion, currentTick) {
79
+ if (cushion.cushionLiq === 0n)
80
+ return bps;
81
+ const gap = cushion.cushionLower - currentTick;
82
+ let m;
83
+ if (gap >= GAP_SKIM_TICKS)
84
+ m = GAP_SKIM_MULT_BPS;
85
+ else if (gap > GAP_SKIM_FROM_TICKS)
86
+ m = 10_000 + Math.floor(((GAP_SKIM_MULT_BPS - 10_000) * (gap - GAP_SKIM_FROM_TICKS)) / (GAP_SKIM_TICKS - GAP_SKIM_FROM_TICKS));
87
+ else
88
+ return bps;
89
+ const scaled = Math.floor((bps * m) / 10_000);
90
+ return scaled > GAP_SKIM_MAX_BPS ? GAP_SKIM_MAX_BPS : scaled;
91
+ }
92
+ /** The hook's four takes off ONE quote leg, each `leg × bps / 10_000` rounded down (`_takeFees`). */
93
+ export function hookTakes(side, leg, skimBps, r) {
94
+ const of = (bps) => (leg * BigInt(bps)) / 10000n;
95
+ const floorSkim = of(skimBps);
96
+ const creator = of(side === 'buy' ? r.creatorBuyBps : r.creatorSellBps);
97
+ const holder = of(side === 'buy' ? r.holderBuyBps : r.holderSellBps);
98
+ const floorPlatform = of(r.teamFeeBps);
99
+ return { floorSkim, creator, holder, floorPlatform, total: floorSkim + creator + holder + floorPlatform };
100
+ }
101
+ const ceilDiv = (a, b) => (a + b - 1n) / b;
102
+ /**
103
+ * A pool swap's five parts, in the QUOTE's smallest unit.
104
+ * - BUY (exact quote in, the leg is `amountIn`): the hook takes its four off the leg BEFORE the swap (`_beforeSwap`), at the
105
+ * PRE-swap tick; the LP fee is the pool's 0.25% of what is left (`ceil`, as v4's swap step rounds it).
106
+ * - SELL (exact tokens in, the leg is the swap's quote output): the hook takes its four AFTER the swap, off the leg; `amountOut`
107
+ * is the leg less them, so the leg is the least value whose remainder covers `amountOut`. The LP fee was charged on the
108
+ * TOKEN input and is stated in quote at the swap's own rate, `leg × fee / (1e6 − fee)` — an estimate.
109
+ * ⚠ A sell's skim is charged at the POST-swap tick (further up the ramp toward the floor); `skimBps` here is whatever the caller
110
+ * read. Pass the pre-trade figure and the skim part is a MINIMUM.
111
+ * A buy's `skimBps` is the figure the engine charges: on contracts with the gap buy skim, `gapSkimBps(skimBpsAt(...), ...)`.
112
+ */
113
+ export function poolFeeParts(side, amountIn, amountOut, skimBps, r) {
114
+ if (side === 'buy') {
115
+ const t = hookTakes('buy', amountIn, skimBps, r);
116
+ const lp = ceilDiv((amountIn - t.total) * LP_FEE_PIPS, 1000000n);
117
+ return feeList(lp, t);
118
+ }
119
+ const bps = skimBps + r.creatorSellBps + r.holderSellBps + r.teamFeeBps;
120
+ if (bps >= 10_000)
121
+ throw new RangeError(`the pool's sell takes sum to ${bps} bps`);
122
+ let leg = (amountOut * 10000n) / BigInt(10_000 - bps);
123
+ while (leg - hookTakes('sell', leg, skimBps, r).total < amountOut)
124
+ leg += 1n;
125
+ while (leg > 0n && leg - 1n - hookTakes('sell', leg - 1n, skimBps, r).total >= amountOut)
126
+ leg -= 1n;
127
+ const t = hookTakes('sell', leg, skimBps, r);
128
+ const lp = ceilDiv(leg * LP_FEE_PIPS, 1000000n - LP_FEE_PIPS);
129
+ return feeList(lp, t);
130
+ }
131
+ /** A bonding trade's take: the sale's FLOOR Platform fee, and the four pool parts at zero (there is no pool yet). */
132
+ export function bondingFeeParts(floorPlatform) {
133
+ return feeList(0n, { floorSkim: 0n, creator: 0n, holder: 0n, floorPlatform });
134
+ }
135
+ function feeList(lp, t) {
136
+ return [
137
+ { kind: 'lp', amount: lp },
138
+ { kind: 'floorSkim', amount: t.floorSkim },
139
+ { kind: 'creator', amount: t.creator },
140
+ { kind: 'holder', amount: t.holder },
141
+ { kind: 'floorPlatform', amount: t.floorPlatform },
142
+ ];
143
+ }
144
+ /** The five kinds an EVM quote lists, in order. A list missing any of them is refused (`assertWholeTake`). */
145
+ export const EVM_FEE_KINDS = ['lp', 'floorSkim', 'creator', 'holder', 'floorPlatform'];
146
+ /** Throws unless `fees` names each of the five EVM parts exactly once — the whole take, or none of it. */
147
+ export function assertWholeTake(fees) {
148
+ const kinds = fees.map((f) => f.kind);
149
+ if (kinds.length !== EVM_FEE_KINDS.length || EVM_FEE_KINDS.some((k) => kinds.filter((x) => x === k).length !== 1)) {
150
+ throw new RangeError(`a quote lists the trader's whole take or none of it; got [${kinds.join(', ')}]`);
151
+ }
152
+ for (const f of fees)
153
+ if (f.amount < 0n)
154
+ throw new RangeError(`the ${f.kind} part is negative`);
155
+ }
156
+ //# sourceMappingURL=fees.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fees.js","sourceRoot":"","sources":["../src/fees.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `@floorlaunchpad/sdk-evm` — FLOOR on EVM chains: ABIs, deployments, viem reads, quotes and unsigned trade builders.
3
+ * `createEvmAdapter` implements `@floorlaunchpad/sdk`'s `FloorChainAdapter`; everything it is built from is exported beside it.
4
+ */
5
+ export * from './abi/index.js';
6
+ export * from './deployments.js';
7
+ export * from './errors.js';
8
+ export * from './pool.js';
9
+ export * from './fees.js';
10
+ export * from './sale.js';
11
+ export * from './router.js';
12
+ export * from './trade.js';
13
+ export * from './reads.js';
14
+ export * from './adapter.js';
15
+ export * from './send.js';
16
+ export * from './events.js';
17
+ export * from './simulate.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `@floorlaunchpad/sdk-evm` — FLOOR on EVM chains: ABIs, deployments, viem reads, quotes and unsigned trade builders.
3
+ * `createEvmAdapter` implements `@floorlaunchpad/sdk`'s `FloorChainAdapter`; everything it is built from is exported beside it.
4
+ */
5
+ export * from './abi/index.js';
6
+ export * from './deployments.js';
7
+ export * from './errors.js';
8
+ export * from './pool.js';
9
+ export * from './fees.js';
10
+ export * from './sale.js';
11
+ export * from './router.js';
12
+ export * from './trade.js';
13
+ export * from './reads.js';
14
+ export * from './adapter.js';
15
+ export * from './send.js';
16
+ export * from './events.js';
17
+ export * from './simulate.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
package/dist/pool.d.ts ADDED
@@ -0,0 +1,63 @@
1
+ /**
2
+ * A FLOOR pool's key, id and price arithmetic, in bigint.
3
+ *
4
+ * - `sqrtPriceAtTick` is v4-core `TickMath.getSqrtPriceAtTick`, exactly.
5
+ * - `bandTicks`, `marketTick` mirror the hook engine's `_bandTicks` and `_market`.
6
+ */
7
+ import { type Address, type Hex } from 'viem';
8
+ /** The native currency in a v4 key. */
9
+ export declare const NATIVE: Address;
10
+ /** Every FLOOR pool is a dynamic-fee pool: the hook overrides the LP fee on every swap. */
11
+ export declare const DYNAMIC_FEE = 8388608;
12
+ export declare const TICK_SPACING = 60;
13
+ /** The LP fee the hook force-overrides onto every swap, in pips (hundredths of a bip): 2,500 = 0.25%. `SingletonFloorEngine.LP_FEE`. */
14
+ export declare const LP_FEE_PIPS = 2500n;
15
+ /** The skim ramp's length in ticks (`SingletonFloorEngine.SKIM_RAMP_TICKS`). */
16
+ export declare const SKIM_RAMP_TICKS = 16094;
17
+ /** The bid band's width before rounding to spacing (`FloorPolicy.BID_BAND_TICKS`). */
18
+ export declare const BID_BAND_TICKS = 120;
19
+ export declare const MIN_TICK = -887272;
20
+ export declare const MAX_TICK = 887272;
21
+ export declare const MIN_SQRT = 4295128739n;
22
+ export declare const MAX_SQRT = 1461446703485210103287273052203988822378723970342n;
23
+ export interface PoolKey {
24
+ currency0: Address;
25
+ currency1: Address;
26
+ fee: number;
27
+ tickSpacing: number;
28
+ hooks: Address;
29
+ }
30
+ /** The launch's pool key: the token against its quote (native by default), sorted, dynamic fee, spacing 60, the hook. */
31
+ export declare function poolKey(token: Address, hook: Address, quote?: Address): PoolKey;
32
+ /** Whether `quote` sits at currency1 of the key; `null` when it is neither currency. */
33
+ export declare function quoteAtCurrency1(key: Pick<PoolKey, 'currency0' | 'currency1'>, quote: Address): boolean | null;
34
+ export declare function poolIdOfKey(k: PoolKey): Hex;
35
+ /** The pool id a key DERIVES. ⛔ The hook stays the source of a launch's id (`hook.poolForAccount(launch)`); this is for
36
+ * checking that a key the caller is about to sign hashes to it. */
37
+ export declare function poolIdOf(token: Address, hook: Address, quote?: Address): Hex;
38
+ /** v4 `PoolManager._pools` mapping slot. */
39
+ export declare const POOLS_SLOT = 6n;
40
+ /** The storage slot of a pool's `Slot0` word in the PoolManager, read through `extsload`. */
41
+ export declare function poolStateSlot(poolId: Hex): Hex;
42
+ export interface Slot0 {
43
+ sqrtPriceX96: bigint;
44
+ tick: number;
45
+ protocolFee: number;
46
+ lpFee: number;
47
+ }
48
+ export declare function decodeSlot0(word: Hex): Slot0;
49
+ /** v4-core `TickMath.getSqrtPriceAtTick`, exactly: Q64.96, rounded up out of Q128.128. */
50
+ export declare function sqrtPriceAtTick(tick: number): bigint;
51
+ /**
52
+ * The price at an ENGINE-FRAME tick (quote at currency0 for every pool, so a dearer token is a LOWER tick), as WHOLE quote
53
+ * per WHOLE token scaled by 1e18 — the shape of `@floorlaunchpad/sdk` `Launch.floorPriceX18`. Rounded down.
54
+ *
55
+ * `1.0001^-tick` is raw quote per raw token (`lib/pool.ts priceFromTick`); `sqrtPriceAtTick(t)² / 2^192 = 1.0001^t`, so
56
+ * raw-per-raw = `2^192 / sqrtP²`, and whole-per-whole × 1e18 = raw-per-raw × 10^(tokenDecimals − quoteDecimals + 18).
57
+ */
58
+ export declare function priceX18AtTick(tick: number, tokenDecimals: number, quoteDecimals: number): bigint;
59
+ /** `FloorMath._ceilToSpacing(BID_BAND_TICKS, spacing)` for a positive band: the engine's `_bandTicks()`. 120 at spacing 60. */
60
+ export declare function bandTicks(tickSpacing: number): number;
61
+ /** The pool's current tick in the ENGINE frame (`_market`): a quote at currency1 maps `-tick - 1`. ⛔ `-tick` is one tick off. */
62
+ export declare function marketTick(rawTick: number, quoteIsCurrency1: boolean): number;
63
+ //# sourceMappingURL=pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAA+C,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAE3F,uCAAuC;AACvC,eAAO,MAAM,MAAM,EAAkB,OAAO,CAAC;AAC7C,2FAA2F;AAC3F,eAAO,MAAM,WAAW,UAAW,CAAC;AACpC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,wIAAwI;AACxI,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,gFAAgF;AAChF,eAAO,MAAM,eAAe,QAAQ,CAAC;AACrC,sFAAsF;AACtF,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,QAAQ,UAAU,CAAC;AAChC,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,QAAQ,cAAc,CAAC;AACpC,eAAO,MAAM,QAAQ,qDAAqD,CAAC;AAE3E,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yHAAyH;AACzH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAE,OAAgB,GAAG,OAAO,CAGvF;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAK9G;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,GAAG,CAO3C;AAED;oEACoE;AACpE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAE,OAAgB,GAAG,GAAG,CAEpF;AAED,4CAA4C;AAC5C,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAE9C;AAED,MAAM,WAAW,KAAK;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,KAAK,CAS5C;AAID,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4BpD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAMjG;AAED,+HAA+H;AAC/H,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,iIAAiI;AACjI,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAE7E"}
package/dist/pool.js ADDED
@@ -0,0 +1,118 @@
1
+ /**
2
+ * A FLOOR pool's key, id and price arithmetic, in bigint.
3
+ *
4
+ * - `sqrtPriceAtTick` is v4-core `TickMath.getSqrtPriceAtTick`, exactly.
5
+ * - `bandTicks`, `marketTick` mirror the hook engine's `_bandTicks` and `_market`.
6
+ */
7
+ import { encodeAbiParameters, keccak256, zeroAddress } from 'viem';
8
+ /** The native currency in a v4 key. */
9
+ export const NATIVE = zeroAddress;
10
+ /** Every FLOOR pool is a dynamic-fee pool: the hook overrides the LP fee on every swap. */
11
+ export const DYNAMIC_FEE = 0x800000;
12
+ export const TICK_SPACING = 60;
13
+ /** The LP fee the hook force-overrides onto every swap, in pips (hundredths of a bip): 2,500 = 0.25%. `SingletonFloorEngine.LP_FEE`. */
14
+ export const LP_FEE_PIPS = 2500n;
15
+ /** The skim ramp's length in ticks (`SingletonFloorEngine.SKIM_RAMP_TICKS`). */
16
+ export const SKIM_RAMP_TICKS = 16094;
17
+ /** The bid band's width before rounding to spacing (`FloorPolicy.BID_BAND_TICKS`). */
18
+ export const BID_BAND_TICKS = 120;
19
+ export const MIN_TICK = -887272;
20
+ export const MAX_TICK = 887272;
21
+ export const MIN_SQRT = 4295128739n;
22
+ export const MAX_SQRT = 1461446703485210103287273052203988822378723970342n;
23
+ /** The launch's pool key: the token against its quote (native by default), sorted, dynamic fee, spacing 60, the hook. */
24
+ export function poolKey(token, hook, quote = NATIVE) {
25
+ const [currency0, currency1] = token.toLowerCase() < quote.toLowerCase() ? [token, quote] : [quote, token];
26
+ return { currency0, currency1, fee: DYNAMIC_FEE, tickSpacing: TICK_SPACING, hooks: hook };
27
+ }
28
+ /** Whether `quote` sits at currency1 of the key; `null` when it is neither currency. */
29
+ export function quoteAtCurrency1(key, quote) {
30
+ const q = quote.toLowerCase();
31
+ if (key.currency1.toLowerCase() === q)
32
+ return true;
33
+ if (key.currency0.toLowerCase() === q)
34
+ return false;
35
+ return null;
36
+ }
37
+ export function poolIdOfKey(k) {
38
+ return keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'address' }, { type: 'uint24' }, { type: 'int24' }, { type: 'address' }], [k.currency0, k.currency1, k.fee, k.tickSpacing, k.hooks]));
39
+ }
40
+ /** The pool id a key DERIVES. ⛔ The hook stays the source of a launch's id (`hook.poolForAccount(launch)`); this is for
41
+ * checking that a key the caller is about to sign hashes to it. */
42
+ export function poolIdOf(token, hook, quote = NATIVE) {
43
+ return poolIdOfKey(poolKey(token, hook, quote));
44
+ }
45
+ /** v4 `PoolManager._pools` mapping slot. */
46
+ export const POOLS_SLOT = 6n;
47
+ /** The storage slot of a pool's `Slot0` word in the PoolManager, read through `extsload`. */
48
+ export function poolStateSlot(poolId) {
49
+ return keccak256(encodeAbiParameters([{ type: 'bytes32' }, { type: 'uint256' }], [poolId, POOLS_SLOT]));
50
+ }
51
+ export function decodeSlot0(word) {
52
+ const v = BigInt(word);
53
+ const raw = Number((v >> 160n) & 0xffffffn);
54
+ return {
55
+ sqrtPriceX96: v & ((1n << 160n) - 1n),
56
+ tick: raw >= 0x800000 ? raw - 0x1000000 : raw,
57
+ protocolFee: Number((v >> 184n) & 0xffffffn),
58
+ lpFee: Number((v >> 208n) & 0xffffffn),
59
+ };
60
+ }
61
+ const MAX_U256 = (1n << 256n) - 1n;
62
+ /** v4-core `TickMath.getSqrtPriceAtTick`, exactly: Q64.96, rounded up out of Q128.128. */
63
+ export function sqrtPriceAtTick(tick) {
64
+ if (!Number.isInteger(tick) || tick < MIN_TICK || tick > MAX_TICK)
65
+ throw new RangeError(`sqrtPriceAtTick: tick ${tick} out of range`);
66
+ const abs = BigInt(Math.abs(tick));
67
+ let r = (abs & 0x1n) !== 0n ? 0xfffcb933bd6fad37aa2d162d1a594001n : 0x100000000000000000000000000000000n;
68
+ const M = [
69
+ [0x2n, 0xfff97272373d413259a46990580e213an],
70
+ [0x4n, 0xfff2e50f5f656932ef12357cf3c7fdccn],
71
+ [0x8n, 0xffe5caca7e10e4e61c3624eaa0941cd0n],
72
+ [0x10n, 0xffcb9843d60f6159c9db58835c926644n],
73
+ [0x20n, 0xff973b41fa98c081472e6896dfb254c0n],
74
+ [0x40n, 0xff2ea16466c96a3843ec78b326b52861n],
75
+ [0x80n, 0xfe5dee046a99a2a811c461f1969c3053n],
76
+ [0x100n, 0xfcbe86c7900a88aedcffc83b479aa3a4n],
77
+ [0x200n, 0xf987a7253ac413176f2b074cf7815e54n],
78
+ [0x400n, 0xf3392b0822b70005940c7a398e4b70f3n],
79
+ [0x800n, 0xe7159475a2c29b7443b29c7fa6e889d9n],
80
+ [0x1000n, 0xd097f3bdfd2022b8845ad8f792aa5825n],
81
+ [0x2000n, 0xa9f746462d870fdf8a65dc1f90e061e5n],
82
+ [0x4000n, 0x70d869a156d2a1b890bb3df62baf32f7n],
83
+ [0x8000n, 0x31be135f97d08fd981231505542fcfa6n],
84
+ [0x10000n, 0x9aa508b5b7a84e1c677de54f3e99bc9n],
85
+ [0x20000n, 0x5d6af8dedb81196699c329225ee604n],
86
+ [0x40000n, 0x2216e584f5fa1ea926041bedfe98n],
87
+ [0x80000n, 0x48a170391f7dc42444e8fa2n],
88
+ ];
89
+ for (const [bit, m] of M)
90
+ if ((abs & bit) !== 0n)
91
+ r = (r * m) >> 128n;
92
+ if (tick > 0)
93
+ r = MAX_U256 / r;
94
+ return (r >> 32n) + (r % (1n << 32n) === 0n ? 0n : 1n);
95
+ }
96
+ /**
97
+ * The price at an ENGINE-FRAME tick (quote at currency0 for every pool, so a dearer token is a LOWER tick), as WHOLE quote
98
+ * per WHOLE token scaled by 1e18 — the shape of `@floorlaunchpad/sdk` `Launch.floorPriceX18`. Rounded down.
99
+ *
100
+ * `1.0001^-tick` is raw quote per raw token (`lib/pool.ts priceFromTick`); `sqrtPriceAtTick(t)² / 2^192 = 1.0001^t`, so
101
+ * raw-per-raw = `2^192 / sqrtP²`, and whole-per-whole × 1e18 = raw-per-raw × 10^(tokenDecimals − quoteDecimals + 18).
102
+ */
103
+ export function priceX18AtTick(tick, tokenDecimals, quoteDecimals) {
104
+ const s = sqrtPriceAtTick(tick);
105
+ const shift = tokenDecimals - quoteDecimals + 18;
106
+ const num = 1n << 192n;
107
+ const den = s * s;
108
+ return shift >= 0 ? (num * 10n ** BigInt(shift)) / den : num / (den * 10n ** BigInt(-shift));
109
+ }
110
+ /** `FloorMath._ceilToSpacing(BID_BAND_TICKS, spacing)` for a positive band: the engine's `_bandTicks()`. 120 at spacing 60. */
111
+ export function bandTicks(tickSpacing) {
112
+ return Math.ceil(BID_BAND_TICKS / tickSpacing) * tickSpacing;
113
+ }
114
+ /** The pool's current tick in the ENGINE frame (`_market`): a quote at currency1 maps `-tick - 1`. ⛔ `-tick` is one tick off. */
115
+ export function marketTick(rawTick, quoteIsCurrency1) {
116
+ return quoteIsCurrency1 ? -rawTick - 1 : rawTick;
117
+ }
118
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Reading FLOOR launches off an EVM chain with viem.
3
+ *
4
+ * - `poolState` is one `eth_call`, decoded at one width (`decodePoolState` refuses any other).
5
+ * - The pool id comes from `hook.poolForAccount(launch)` — THE HOOK IS THE SOURCE OF THE ID, never the registry entry or a
6
+ * derived key. The pool's own FLOOR Platform fee is read off `poolState.teamFeeBps` and cap-checked.
7
+ * - The sale's getters are read in one batch; its `teamFeeBps()` only on a set whose row names a team vault.
8
+ * - The deployer is `factory.creatorOf(launch)` on the entry's registrar; the published floor is `1.0001^-floorTick`.
9
+ *
10
+ * ⛔ Nothing here lists by draining a chain. `listLaunches` reads ONE registry page per call (newest first) and hands back a
11
+ * cursor; `getLaunch` resolves a token by its own `launch()` and the registry's `isRegistered`, then finds its entry in a
12
+ * BOUNDED newest-first scan (`maxRegistryScan`), remembering every entry it has seen.
13
+ */
14
+ import { type Address, type ContractFunctionReturnType, type Hex, type PublicClient } from 'viem';
15
+ import type { Launch } from '@floorlaunchpad/sdk';
16
+ import { HOOK_ABI, REGISTRY_ABI } from './abi/index.js';
17
+ import { type Deployment } from './deployments.js';
18
+ import { type CushionEdge, type PoolRates } from './fees.js';
19
+ import { type PoolKey, type Slot0 } from './pool.js';
20
+ import { type SaleReads } from './sale.js';
21
+ /** One pool's stored state exactly as `hook.poolState(id)` answers it — a NAMED object. */
22
+ export type PoolStateTuple = ContractFunctionReturnType<typeof HOOK_ABI, 'view', 'poolState'>;
23
+ /** One `FloorRegistry.Entry`. */
24
+ export type RegistryEntry = ContractFunctionReturnType<typeof REGISTRY_ABI, 'view', 'page'>[number];
25
+ /** The registry's page size. */
26
+ export declare const REGISTRY_PAGE_MAX = 500n;
27
+ /** Everything chain-specific this package reads about a launch — `Launch.raw`. */
28
+ export interface EvmLaunchRaw {
29
+ chainId: number;
30
+ launch: Address;
31
+ token: Address;
32
+ hook: Address;
33
+ /** The hook's own id for the pool (`poolForAccount(launch)`). */
34
+ poolId: Hex;
35
+ /** The pool key; it hashes to `poolId` (checked). */
36
+ poolKey: PoolKey;
37
+ rewards: Address;
38
+ /** The factory that registered the launch. */
39
+ registrar: Address;
40
+ /** Unix seconds the registry stamped. */
41
+ registeredAt: bigint;
42
+ /** The quote token; `null` = native. */
43
+ quoteToken: Address | null;
44
+ quoteIsCurrency1: boolean;
45
+ /** The deployer (`creatorOf`), `null` where the factory names nobody or could not be read. */
46
+ creator: Address | null;
47
+ /** The sale's book while bonding; `null` once graduated. */
48
+ sale: SaleReads | null;
49
+ /** The SALE's FLOOR Platform fee, bps — what a bonding buy or sell-back pays; 0 on a set without the fee; `null` once
50
+ * graduated (not read: no bonding trade is left). */
51
+ saleTeamFeeBps: number | null;
52
+ /** The POOL's rates (copied at creation): skim endpoints, creator fee, holder tax, FLOOR Platform fee. */
53
+ poolRates: PoolRates;
54
+ /** The published floor's tick (the band's CHEAP edge, engine frame) and the bid band's width in ticks. */
55
+ floorTick: number;
56
+ bidWidth: number;
57
+ poolState: PoolStateTuple;
58
+ }
59
+ export type EvmLaunch = Launch<EvmLaunchRaw>;
60
+ /** `poolState(id)` calldata. */
61
+ export declare function poolStateCalldata(id: Hex): Hex;
62
+ /** The raw `poolState` return → the named tuple. ⛔ A return of any width but `POOL_STATE_WORDS` is refused by name; viem
63
+ * itself would decode a longer one without complaint. */
64
+ export declare function decodePoolState(data: Hex): PoolStateTuple;
65
+ /** ONE `eth_call` of `poolState(id)`, decoded through `decodePoolState`. */
66
+ export declare function readPoolState(client: Pick<PublicClient, 'call'>, hook: Address, id: Hex): Promise<PoolStateTuple>;
67
+ /** A pool's rates off its state, the FLOOR Platform fee checked against its cap (`RateAboveCap` past it). */
68
+ export declare function poolRatesOf(st: PoolStateTuple): PoolRates;
69
+ /** The pool's `Slot0` off the PoolManager (`extsload` of the pool's state slot). */
70
+ export declare function readSlot0(client: Pick<PublicClient, 'readContract'>, poolManager: Address, poolId: Hex): Promise<Slot0>;
71
+ /** Whether a viem error is a contract REVERT (an answer: "no"), as opposed to a transport failure (not an answer). */
72
+ export declare function isRevert(e: unknown): boolean;
73
+ export declare function readRegistryCount(client: Pick<PublicClient, 'readContract'>, d: Deployment): Promise<bigint>;
74
+ export declare function readRegistryPage(client: Pick<PublicClient, 'readContract'>, d: Deployment, start: bigint, n: bigint): Promise<readonly RegistryEntry[]>;
75
+ /**
76
+ * The launch contract behind a token, checked against THIS chain's registry. A token whose `launch()` reverts, is zero, or is
77
+ * not registered here is not a FLOOR launch on this chain: `FloorEvmError('not_a_launch')`.
78
+ */
79
+ export declare function launchOfToken(client: Pick<PublicClient, 'readContract'>, d: Deployment, token: Address): Promise<Address>;
80
+ /** A quote asset's address, symbol and decimals. Native: the chain's symbol and 18. */
81
+ export declare function readQuoteAsset(client: Pick<PublicClient, 'readContract'>, chainId: number, quote: Address | null, nativeSymbol?: string): Promise<{
82
+ address: string | null;
83
+ symbol: string;
84
+ decimals: number;
85
+ }>;
86
+ /** The sale's getters in one batch, checked (`saleReadsFrom`). The fee is asked only on a set that carries it. */
87
+ export declare function readSale(client: Pick<PublicClient, 'readContract'>, d: Deployment, launch: Address): Promise<SaleReads>;
88
+ /** The hook's id for the launch's pool. A revert or a zero id is "not a launch this hook serves". */
89
+ export declare function readPoolId(client: Pick<PublicClient, 'readContract'>, hook: Address, launch: Address): Promise<Hex>;
90
+ /**
91
+ * A launch, read whole from its registry entry: the token, the sale or the pool, the rates, the floor. Every rate is read
92
+ * off this launch's own contracts; nothing is assumed.
93
+ */
94
+ export declare function readLaunchFromEntry(client: PublicClient, d: Deployment, e: RegistryEntry, opts?: {
95
+ nativeSymbol?: string;
96
+ }): Promise<EvmLaunch>;
97
+ /**
98
+ * The pool's staircase cushion edge (`stairs()` through `hook.execute(poolId, …)`): what the gap buy skim reads.
99
+ * `cushionLiq` 0 = no cushion standing.
100
+ */
101
+ export declare function readCushion(client: Pick<PublicClient, 'call'>, hook: Address, poolId: Hex): Promise<CushionEdge>;
102
+ /** Reads a holder's sale position (`allocation`, `contributed`) — what a sell-back pays against. */
103
+ export declare function readSalePosition(client: Pick<PublicClient, 'readContract'>, launch: Address, holder: Address): Promise<{
104
+ allocation: bigint;
105
+ contributed: bigint;
106
+ }>;
107
+ //# sourceMappingURL=reads.d.ts.map