@black-market/sdk 0.9.1 → 0.11.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 (72) hide show
  1. package/README.md +23 -17
  2. package/dist/lifecycle/abi.d.ts +1 -0
  3. package/dist/lifecycle/abi.d.ts.map +1 -1
  4. package/dist/lifecycle/abi.js +1 -0
  5. package/dist/lifecycle/abi.js.map +1 -1
  6. package/dist/lifecycle/calibration.d.ts.map +1 -1
  7. package/dist/lifecycle/calibration.js +2 -0
  8. package/dist/lifecycle/calibration.js.map +1 -1
  9. package/dist/lifecycle/deployments/{hmm-dynamic-pool-hook-v1-20261011.d.ts → hmm-dynamic-pool-hook-v2-20261017.d.ts} +21 -21
  10. package/dist/lifecycle/deployments/{hmm-dynamic-pool-hook-v1-20261011.d.ts.map → hmm-dynamic-pool-hook-v2-20261017.d.ts.map} +1 -1
  11. package/dist/lifecycle/deployments/hmm-dynamic-pool-hook-v2-20261017.js +69 -0
  12. package/dist/lifecycle/deployments/{hmm-dynamic-pool-hook-v1-20261011.js.map → hmm-dynamic-pool-hook-v2-20261017.js.map} +1 -1
  13. package/dist/lifecycle/deployments/{hmm-fixed-pool-hook-v1-20261011.d.ts → hmm-fixed-pool-hook-v2-20261017.d.ts} +21 -21
  14. package/dist/lifecycle/deployments/{hmm-fixed-pool-hook-v1-20261011.d.ts.map → hmm-fixed-pool-hook-v2-20261017.d.ts.map} +1 -1
  15. package/dist/lifecycle/deployments/hmm-fixed-pool-hook-v2-20261017.js +69 -0
  16. package/dist/lifecycle/deployments/{hmm-fixed-pool-hook-v1-20261011.js.map → hmm-fixed-pool-hook-v2-20261017.js.map} +1 -1
  17. package/dist/lifecycle/hmm-abi.d.ts +4544 -0
  18. package/dist/lifecycle/hmm-abi.d.ts.map +1 -0
  19. package/dist/lifecycle/hmm-abi.js +299 -0
  20. package/dist/lifecycle/hmm-abi.js.map +1 -0
  21. package/dist/lifecycle/hmm.d.ts +19 -3
  22. package/dist/lifecycle/hmm.d.ts.map +1 -1
  23. package/dist/lifecycle/hmm.js +11 -7
  24. package/dist/lifecycle/hmm.js.map +1 -1
  25. package/dist/lifecycle/markets.d.ts.map +1 -1
  26. package/dist/lifecycle/markets.js +2 -0
  27. package/dist/lifecycle/markets.js.map +1 -1
  28. package/dist/lifecycle/planner.d.ts.map +1 -1
  29. package/dist/lifecycle/planner.js +44 -35
  30. package/dist/lifecycle/planner.js.map +1 -1
  31. package/dist/lifecycle/presets.d.ts +7 -2
  32. package/dist/lifecycle/presets.d.ts.map +1 -1
  33. package/dist/lifecycle/presets.js +19 -5
  34. package/dist/lifecycle/presets.js.map +1 -1
  35. package/dist/lifecycle/rpc.js +3 -2
  36. package/dist/lifecycle/rpc.js.map +1 -1
  37. package/dist/lifecycle/simulation.d.ts +1 -1
  38. package/dist/lifecycle/simulation.d.ts.map +1 -1
  39. package/dist/lifecycle/simulation.js +115 -174
  40. package/dist/lifecycle/simulation.js.map +1 -1
  41. package/dist/lifecycle/transactions.d.ts +6 -0
  42. package/dist/lifecycle/transactions.d.ts.map +1 -1
  43. package/dist/lifecycle/transactions.js +39 -0
  44. package/dist/lifecycle/transactions.js.map +1 -1
  45. package/dist/lifecycle/types.d.ts +6 -3
  46. package/dist/lifecycle/types.d.ts.map +1 -1
  47. package/dist/lifecycle/types.js.map +1 -1
  48. package/docs/launch-lifecycle.md +197 -86
  49. package/examples/.env.example +4 -0
  50. package/examples/README.md +27 -6
  51. package/examples/hmm-launch-config.ts +4 -1
  52. package/examples/launch-example-support.ts +1 -0
  53. package/examples/launch-example.ts +1 -0
  54. package/examples/launch.ts +1 -0
  55. package/package.json +2 -2
  56. package/src/lifecycle/abi.ts +1 -0
  57. package/src/lifecycle/calibration.ts +1 -0
  58. package/src/lifecycle/deployments/hmm-dynamic-pool-hook-v2-20261017.ts +71 -0
  59. package/src/lifecycle/deployments/hmm-fixed-pool-hook-v2-20261017.ts +71 -0
  60. package/src/lifecycle/hmm-abi.ts +302 -0
  61. package/src/lifecycle/hmm.ts +12 -7
  62. package/src/lifecycle/markets.ts +1 -0
  63. package/src/lifecycle/planner.ts +41 -32
  64. package/src/lifecycle/presets.ts +20 -6
  65. package/src/lifecycle/rpc.ts +3 -2
  66. package/src/lifecycle/simulation.ts +111 -165
  67. package/src/lifecycle/transactions.ts +38 -1
  68. package/src/lifecycle/types.ts +9 -4
  69. package/dist/lifecycle/deployments/hmm-dynamic-pool-hook-v1-20261011.js +0 -69
  70. package/dist/lifecycle/deployments/hmm-fixed-pool-hook-v1-20261011.js +0 -69
  71. package/src/lifecycle/deployments/hmm-dynamic-pool-hook-v1-20261011.ts +0 -71
  72. package/src/lifecycle/deployments/hmm-fixed-pool-hook-v1-20261011.ts +0 -71
@@ -7,6 +7,50 @@ The canonical authorities are the registry/certification/adapter/config contract
7
7
  in the protocol repository. Plan identity is `LaunchPlanV1`. Pool-bound V4 uses **config 6**,
8
8
  canonical Abyss uses **config 1**, and generic current shared-V4 support uses **config 4**.
9
9
 
10
+ ## 0.11.0 release: gas sizing, packing and prefix proof
11
+
12
+ New atomic/activation envelopes containing HMM V2 markets add one forwarding target:
13
+ `R = 4_250_000 + 500_000 * (hmmMarkets - 1)` gas (zero for non-HMM plans).
14
+ For measured gross gas `G` (`maxUsedGas`, falling back to `gasUsed`), compute is
15
+ `min(max(G + R, ceil(G * (10000 + headroomBps) / 10000)), computeCap)`.
16
+ Begin/preparation/approval/cancel commands do not receive this reserve. Nitro poster
17
+ gas is budgeted separately inside the same complete gas envelope. Optional padding
18
+ and the reserve are targets, not refusal thresholds; exact validated replay proves
19
+ the clamped envelope. There is no bisection or extra ordinary-path request.
20
+
21
+ Staged planning greedily packs contiguous markets against the unpadded compute cap:
22
+ HMM V2 costs 14.5M per market; other profiles cost a conservative 16M. At 32M,
23
+ 1/2/3/5 HMM markets produce `[1]`/`[2]`/`[2,1]`/`[2,2,1]`.
24
+ Only a packed measurement failure consuming at least 95% of its given gas splits
25
+ that batch in half, regardless of its error selector. Low-gas semantic failures
26
+ remain failures. `preparationBatchSize` is removed; inspect each preparation's
27
+ `marketStart`/`marketCount`. The pure unsigned compiler still accepts explicit
28
+ `preparationBatches`.
29
+
30
+ Robinhood chain 4663 defaults `limits.maxSimulationGas` to **50_000_000n** aggregate
31
+ gas **used**, not the sum of individual legal transaction envelopes. Override it
32
+ for a provider with a different budget. The SDK measures and validates the longest
33
+ estimated prefix that fits: begin 9.5M, preparations as above, activation 6M per
34
+ market plus `R`, and small approvals/cancellation. A measurement failure after
35
+ cumulative use reaches 95% of that cap defers the failed call and suffix.
36
+ If even the immediate estimate cannot fit that budget, refusal first identifies
37
+ any estimated per-transaction compute overflow (gas displayed in millions to one
38
+ decimal), rather than suggesting that a larger RPC budget solves it. Estimates
39
+ alone do not reject an envelope that can still be measured and exactly proved.
40
+
41
+ `simulation.admitted`, `executionProof: "proved"` and `protocolFit: "proved"` cover
42
+ only the successful proven prefix. **They do not promise eventual activation.**
43
+ `simulation.deferredTransactionIds` explicitly lists unproved remaining steps
44
+ (empty for full coverage); these commands carry no `gas`, `gasPrice`, `estimate`
45
+ or `admission`. Call `buildNextTransaction` before each signature: canonical
46
+ progress advances the proof window and gives the immediate next transaction exact
47
+ gas. Reviewed envelopes receive only a direct exact replay of that immediate step,
48
+ without new measurement, poster/price recommendations or suffix proof.
49
+
50
+ `buySlippageBps` requires actual activation outputs. If activation is deferred,
51
+ calibration refuses clearly; use a higher-budget native provider or preserve
52
+ already committed minima by omitting recalibration. Outputs are never fabricated.
53
+
10
54
  ## 0.9.1 release: Abyss 0.01% fee tier
11
55
 
12
56
  `ABYSS_FEE_TIERS` now includes `{ feePips: 100, tickSpacing: 1, label: "0.01%" }`.
@@ -20,72 +64,138 @@ The Robinhood chain 4663 factory has enabled fee 100 with spacing 1. Other
20
64
  deployments must enable the tier before execution; local recipe construction is
21
65
  not evidence of live profile admission. Existing tiers and defaults are unchanged.
22
66
 
23
- ## 0.9.0 release: HMM pool hooks
67
+ ## 0.10.0 release: HMM V2 only
68
+
69
+ The admitted October17 **HMM Fixed V2** and **HMM Dynamic V2** replace the SDK's
70
+ earlier HMM offerings. Generic keys `KnownLifecycleProfile.V4HmmFixedPool`
71
+ (`v4-hmm-fixed-pool`) and `V4HmmDynamicPool` (`v4-hmm-dynamic-pool`) now select V2.
72
+ Versioned hook keys are `KnownLifecycleHook.HmmFixedPoolV2` / `HmmDynamicPoolV2`.
73
+ These are not aliases for the non-HMM fixed/dynamic hooks; those APIs are unchanged.
24
74
 
25
- The October11 registered **HMM Fixed** and **HMM Dynamic** use
26
- `KnownLifecycleProfile.V4HmmFixedPool` (`v4-hmm-fixed-pool`) and
27
- `KnownLifecycleProfile.V4HmmDynamicPool` (`v4-hmm-dynamic-pool`), with hook keys
28
- `KnownLifecycleHook.HmmFixedPoolV1` / `HmmDynamicPoolV1`. Their frozen profile,
29
- adapter, envelope, graph, runtime hashes and creation code come from Black Market
30
- main `1ca9881`, admissions `20261011T214314Z-hmm-fixed` and
31
- `20261011T220032Z-hmm-dynamic`. Each graph has its own HMM collector/deployer and
32
- locker; these are not aliases for the existing fixed/dynamic hooks.
33
- Live `readLifecycleProfiles` remains the authority for `admitted`, not the presets.
75
+ | Preset | Admitted V2 profile ID |
76
+ | --- | --- |
77
+ | HMM Fixed V2 (`hooks/hmm-fixed-v2`) | `0x45e957bcc7068350a65f5b4de5453b674d54d0f5eb2a88fc839da13197e80e98` |
78
+ | HMM Dynamic V2 (`hooks/hmm-dynamic-v2`) | `0x8e500f203ace505072e209c5f077e11de6d071ac7f298cd75c0e05c6a55c36e6` |
34
79
 
35
- Both require `lpFeePips: 0` and `developerFeeBps: 0`. Fixed uses `hookFeePips`
36
- as the static trading fee; Dynamic uses the same minimum/maximum/sensitivity
37
- policy as the Dynamic Fee Hook. Config6 requires `hmmLaunchConfig`:
80
+ Frozen adapters, envelopes, complete dependency graphs, creation code and admission
81
+ fixtures preserve the V2 release and pinned registry readback at block 91,874,655.
82
+ Each graph has its own collector/deployer, locker and hook deployer. Presets are
83
+ construction data, not a current admission certificate: live
84
+ `readLifecycleProfiles` and execution proof remain authoritative.
85
+
86
+ Both require `lpFeePips: 0` and `developerFeeBps: 0`. Fixed charges `hookFeePips`
87
+ as its static fee; Dynamic uses config6 minimum/maximum/sensitivity policy.
88
+ Config6 requires a typed `hmmLaunchConfig`:
38
89
 
39
90
  ```ts
40
91
  const hmmLaunchConfig = defaultHmmLaunchConfig({
41
92
  tokenBudget: marketTokenBudget, quoteAsset: "USDG", quoteDecimals: 6,
93
+ // Illustrative caller choices, not SDK risk defaults:
94
+ maxBidQuote: 100n * 10n ** 6n, // maximum 100 USDG of new/refreshed bid principal
95
+ referenceDeviation: 0, // do not ask below or bid above the rounded reference
42
96
  });
43
- // Optional explicit UI choices:
44
- hmmLaunchConfig.strategyShareBps = 2500; // 25%; default 50%; 100% is also valid.
45
- hmmLaunchConfig.strategy.premiumDecaySeconds = 259200; // 72h; default off (0).
97
+ hmmLaunchConfig.strategyShareBps = 2500; // optional 25%; existing default is 50%
98
+ hmmLaunchConfig.strategy.premiumDecaySeconds = 259200; // optional 72h; default off
46
99
  const config = encodePoolBoundV4LifecycleMarketConfig({
47
100
  ...reviewedV6Fields, lpFeePips: 0, developerFeeBps: 0, hmmLaunchConfig,
48
101
  });
49
102
  ```
50
103
 
51
- `HmmStrategyConfig` / `HmmLaunchConfig` mirror Solidity
52
- `HMMStrategyConfigV1` / `HMMLaunchConfigV1`; `encodeHmmLaunchTail` produces exactly
53
- `abi.encode(HMMLaunchConfigV1)` (448 bytes). The V6 codec automatically appends it
54
- only for HMM profile IDs and rejects a missing tail. Decoding preserves the typed
55
- tail through `prepareAndPlanLifecycleLaunch` salt mining and recovery; plain V6,
56
- noncanonical prefixes and incorrectly sized tails are rejected before RPC planning.
57
- The full plan hash includes the tail. The hook constructor's market-economics
58
- commitment hashes only the canonical V6 prefix with zero salt, exactly as the
59
- HMM collector factory does.
60
-
61
- `validateHmmLaunchConfig` mirrors the collector factory: share <=10,000 bps;
62
- positive bid/ask widths and stale displacement, nonnegative gap, positive stale
63
- seconds and harvest thresholds; resale premium <=5,000 bps; 1–8 asks; exposure
64
- >= ask count and minimum token harvest; inventory >= minimum token harvest;
65
- both caps <= uint128 max. Solidity int24/uint32/uint256 widths are enforced.
66
- Minimum quote deployment may be zero; premium decay is any uint32.
67
- Widths, gap and displacement are **tick spacings**, not raw ticks.
68
-
69
- Defaults: 50% share; widths 5/5, gap 1, stale 86,400 seconds/displacement 5,
70
- resale premium 500 bps, 4 asks, decay off. Token thresholds are raw market-budget
71
- ratios: harvest budget/100,000, ask exposure budget/10, acquired inventory budget.
72
- Budgets too small to produce a positive harvest or above uint128 are rejected.
73
- WETH minimum quote deploy/harvest is 0.0005/0.005 ETH; USDG is 1/10 six-decimal
74
- units. Symbols and canonical catalog addresses work; supplied decimals must match.
75
- Other quotes require explicit `minQuoteDeploy` and `minQuoteHarvest` raw values.
76
- Do not infer USD prices or units for unsupported assets.
77
-
78
- Each harvest sends the share of collected **QUOTE** fees to the per-market manager;
79
- the remainder follows the normal owner/holder-reward split. Token-side fees are
80
- untouched. The fee owner may call `HMMFeeCollectorV1.setStrategyShareBps` later.
81
- The manager bids below price and re-sells acquired inventory at/above realized
82
- cost plus premium; it never touches the locked launch positions.
83
-
84
- Independent Solidity ABI fixtures are generated by
85
- `node scripts/generate-hmm-fixtures.mjs` (Foundry `cast abi-encode`). Snapshot
86
- regeneration uses `node --experimental-transform-types scripts/generate-hmm-presets.mjs
87
- /path/to/black-market`; it reads hash-checked storage-child runtime code from
88
- Robinhood without modifying the evidence checkout.
104
+ `HmmStrategyConfig` / `HmmLaunchConfig` are V2-only and mirror Solidity
105
+ `HMMStrategyConfigV2` / `HMMLaunchConfigV2`. `encodeHmmLaunchTail` produces exactly
106
+ `abi.encode(HMMLaunchConfigV2)`: **16 static words / 512 bytes**. The V6 codec
107
+ appends the tail only for current HMM profile IDs. Missing tails, old 448-byte
108
+ tails, extra words and noncanonical prefixes are rejected before RPC planning.
109
+ Mining and recovery preserve the typed tail. The full launch-plan hash binds
110
+ every tail byte, including both new guards.
111
+
112
+ The hook constructor is still **one 20-word / 640-byte
113
+ `PoolBoundHookParametersV2` tuple**. Do not append the HMM tail to creation code.
114
+ The collector factory hashes only the canonical config6 prefix with zero hook
115
+ salt for the hook's market-economics commitment; the auxiliary strategy settings
116
+ are handed to the manager through the collector. Changing those settings changes
117
+ the full plan commitment, but not the hook constructor's prefix-only commitment.
118
+
119
+ `validateHmmLaunchConfig` enforces the factory's exact launch guards and Solidity
120
+ field widths. Share is 0..10,000 bps. All 15 strategy fields are listed in wire order:
121
+
122
+ | Field | Unit and accepted launch values |
123
+ | --- | --- |
124
+ | `bidWidth` | Tick spacings; positive int24 |
125
+ | `askWidth` | Tick spacings; positive int24 |
126
+ | `gap` | Tick spacings; nonnegative int24 |
127
+ | `staleAfterSeconds` | Positive uint32 seconds |
128
+ | `staleDisplacement` | Tick spacings; positive int24 |
129
+ | `minQuoteDeploy` | Raw quote units; any uint256, including zero |
130
+ | `minQuoteHarvest` | Raw quote units; positive uint256 |
131
+ | `minTokenHarvest` | Raw launch-token units; positive, covered by both token caps |
132
+ | `resalePremiumBps` | 0..5,000 bps |
133
+ | `maxAsks` | 1..8 |
134
+ | `maxAskTokenExposure` | Raw launch-token units; at least ask count and minimum token harvest, at most uint128 max |
135
+ | `maxAcquiredInventory` | Raw launch-token units; at least minimum token harvest, at most uint128 max |
136
+ | `premiumDecaySeconds` | Any uint32 seconds; zero disables decay |
137
+ | `maxBidQuote` | Raw quote-principal ceiling for new/refreshed bids; positive and at most uint128 max |
138
+ | `referenceDeviation` | Tick spacings; nonnegative int24 |
139
+
140
+ For reference pool tick `R`, deviation `D` and spacing `S`, ask lower is at least
141
+ `R - D*S` and bid upper is at most `R + D*S`, with side-appropriate grid rounding.
142
+ The reference comes from the hook's truncated oracle, not an independent spot
143
+ price supplied by the caller.
144
+
145
+ The default helper **requires explicit `maxBidQuote` and `referenceDeviation`**;
146
+ neither has a guessed risk default. All other defaults are preserved: 50% share,
147
+ widths 5/5, gap 1, stale 86,400 seconds/displacement 5, premium 500 bps, 4 asks,
148
+ decay off. Token thresholds are raw market-budget ratios: harvest budget/100,000,
149
+ ask exposure budget/10, inventory budget. Too-small budgets producing zero harvest
150
+ and budgets above uint128 are rejected. WETH quote deploy/harvest thresholds remain
151
+ 0.0005/0.005 ETH; USDG is 1/10 six-decimal units. Catalog symbols/addresses work;
152
+ explicit decimals must match. Other quotes require explicit `minQuoteDeploy` and
153
+ `minQuoteHarvest`; no unsupported asset's USD price or units are inferred.
154
+
155
+ ### V2 fee funding and owner controls
156
+
157
+ V2 reserves the strategy share **on each swap in both pool currencies, after the
158
+ protocol treasury share**, rather than waiting for harvest. The remaining fees
159
+ follow the normal fee-hub distribution. HMM itself does not burn fees and never
160
+ touches the permanently locked launch positions.
161
+
162
+ The browser-safe lifecycle and root exports include complete
163
+ `hmmLiquidityManagerV2Abi`, `hmmFeeCollectorV2Abi`, `hmmFeeCollectorFactoryV2Abi`,
164
+ `hmmFixedHookV2Abi` and `hmmDynamicHookV2Abi`. Use ordinary viem contract calls;
165
+ the SDK adds no speculative transaction wrappers:
166
+
167
+ - Read `strategyOwner()` and `liquidityManager()` on the collector. Authority
168
+ follows the **current** fee owner from the canonical hub/fee-owner registry.
169
+ - Call collector `setStrategyShareBps(uint16)` for 0..10,000 bps. It changes future
170
+ swap reservations, not fees already reserved.
171
+ - Read manager `strategyConfig()` for the complete 15-field tuple, then call
172
+ `setStrategyConfig(HMMStrategyConfigV2)` to update every setting immediately.
173
+ This queues a book refresh for the next maintenance pass. Lowering intake caps
174
+ does not forcibly liquidate existing inventory; existing lots keep their stored
175
+ floor and age. New premium settings apply to newly acquired lots.
176
+ - Read `placementsPaused()` and call `setPlacementsPaused(bool)` on the manager.
177
+ Pausing queues auxiliary-liquidity withdrawal on maintenance and stops new
178
+ placements, not trading or fee collection. It does not withdraw locked launch LP.
179
+
180
+ These writes require the current fee-owner wallet and explicit transaction
181
+ authorization. Read-only planning never invokes them.
182
+
183
+ ### Breaking migration from the earlier HMM SDK
184
+
185
+ Rebuild unstarted HMM plans with the new preset IDs/adapters/graphs, supply both
186
+ new guards, re-encode the 512-byte tail, and re-mine/re-prove the resulting plan.
187
+ Do not pad old 448-byte payloads, reuse an old graph/salt, or relabel old bytes.
188
+ The former `HmmFixedPoolV1` / `HmmDynamicPoolV1` enum members and old HMM metadata
189
+ have no compatibility aliases. Existing onchain HMM V1 profiles/markets were not
190
+ deregistered or upgraded by this SDK release; submitted legacy plans must not be
191
+ mutated into V2 plans. Use tooling matching their original contract release.
192
+
193
+ Independent Solidity ABI fixtures are regenerated with
194
+ `node scripts/generate-hmm-fixtures.mjs` (Foundry `cast abi-encode` / `calldata`).
195
+ To regenerate canonical V2 metadata/ABIs from preserved evidence without RPC or
196
+ onchain writes, use `node --experimental-transform-types
197
+ scripts/generate-hmm-presets.mjs release.json live.json`; both JSON files must be
198
+ the exact V2 release and matching successful admission/pinned-readback records.
89
199
 
90
200
  ## 0.8.1 release
91
201
 
@@ -276,15 +386,13 @@ progress, funding/allowances and deployment/profile authority. It matches
276
386
  Preparation batching remains SDK-derived, not caller-selected. Malformed,
277
387
  wrong-step or changed envelopes refuse without returning executable calldata.
278
388
 
279
- Fresh measurement and complete native validated replay use the held price.
280
- The immediate replay uses the exact held gas; later unfinished steps receive
281
- fresh gas bounds and remain in the same stateful sequence. Current compute,
282
- poster, minimum headroom, tightening ceilings and full-sequence actual-balance
283
- affordability still apply. Exact replay also checks gross-gas headroom without
284
- counting Nitro's temporary compute hold. Neither natural child base fees nor
285
- payer balances are overridden. A higher advisory quote alone is not a refusal;
286
- an invalid current fee, insufficient gas or failed proof never silently raises
287
- the held envelope.
389
+ The SDK directly validates only the immediate transaction at its exact held
390
+ gas/price. It does not repeat measurement, quote a new gas price/poster budget or
391
+ simulate future steps. Current protocol/transaction limits, native metering,
392
+ postconditions and immediate actual-balance affordability still apply. Existing
393
+ padding may be consumed; neither a new padding target nor a higher advisory quote
394
+ alone invalidates a held envelope. Natural child base fees and payer balances are
395
+ never overridden, and failed replay never raises held gas or switches backend.
288
396
 
289
397
  Approvals/resets, atomic launches, every staged next step and cancellation use
290
398
  this same contract. Cancellation retains its adapter-independent recovery policy.
@@ -676,13 +784,13 @@ Validation uses `validateV4LifecycleMarket`; the collector factory getter is
676
784
  | --- | --- |
677
785
  | `readLifecycleProfiles({client, orchestrator, profileIds?, offset?, limit?})` | Bounded registry discovery, schema/topology dispatch, reviewed graph/terms certification and current registry admission. Default offset/limit is 0/100; explicit IDs can select a reviewed deployment's identities. |
678
786
  | `predictLifecycleToken({client, plan})` | Exact prediction from the explicit core. |
679
- | `prepareAndPlanLifecycleLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market launch topology and exact final deployment bindings, and returns complete selected-mode admission under one SDK-owned fresh post-mining snapshot. No source-chain deployment or broadcast. |
787
+ | `prepareAndPlanLifecycleLaunch({client, account, plan, mode, buySlippageBps?, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market topology and exact final deployment bindings, and proves the selected-mode prefix under one fresh post-mining snapshot. Reports deferred steps; buy calibration requires activation coverage. No source-chain deployment or broadcast. |
680
788
  | `readPoolBoundHookDeployment({client, plan, marketIndex})` | Verifies typed factory, code chunks, constructor, normalized economics, initcode, salt, CREATE2 prediction and recorded provenance of existing code. Works with draft salts; permission bits are additionally required for executable predeployment. |
681
789
  | `buildPoolBoundHookDeploymentTransaction({client, plan, marketIndex})` | Optional permissionless typed `deploy(parameters,salt)` calldata. Does not create a token, register/initialize a pool, bind a collector or activate a launch. |
682
790
  | `planLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?})` | Independently fresh per-market topology/domain/funding/profile/progress/execution admission of the already-finalized commitment, simulating only the explicitly selected mode. |
683
791
  | `simulateLaunchPlan({client, planned, limits?, fork?, receipts?, confirmations?})` | Rereads canonical state and proves remaining work. Preserves receipt evidence, economics and selected mode. |
684
792
  | `readLaunchProgress({client, planned, receipts?, confirmations?})` | Confirmation-bound canonical state, latest head, receipt/replacement/reorg status, account-nonce safety and actual prepared market/live state. |
685
- | `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads progress, constraints and complete stateful proof before returning one admitted transaction. Optional untrusted `reviewedTransaction` must match the current canonical next step and freshly prove its exact gas/price. Optional `submissionClient` adds read-only immediate exact-envelope preflight. `action: "cancel"` uses the stored commitment without requiring fresh adapter/profile admission. Terminal launches return `undefined`. |
793
+ | `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads canonical progress and constraints, proves the immediate next transaction plus the fitting prefix, and returns one admitted envelope. With `reviewedTransaction`, directly replays only that matching immediate step at its exact held gas/price. Optional `submissionClient` adds read-only exact-envelope preflight. `action: "cancel"` retains adapter-independent recovery. Terminal launches return `undefined`. |
686
794
 
687
795
  Clients may be viem public clients or raw `request({method,params})` RPC clients. Transport, wallet, signing and durable storage are application-owned. `PlannedLaunch` contains bigint values and live limit callbacks: persist `serializeLaunchPlan(plan)`, explicit execution mode, confirmation policy and receipt references, not the entire object.
688
796
 
@@ -813,17 +921,17 @@ Mining is cancellable/nonblocking; `abort()` raises `AbortError` and does not ca
813
921
  Every planning call requires `mode: "atomic" | "staged"`. Only that requested mode receives economic simulation; staged does not compute or expose an unused atomic attempt.
814
922
 
815
923
  - Atomic: after funding prerequisites, token creation, empty infrastructure, all mint/lock/buys/public activation are one transaction.
816
- - Staged: prerequisites, `beginLaunch(Staged)`, contiguous empty `prepareMarkets` batches, then one `activateLaunch`. Only a stateful preparation refusal classified as capacity with a compute or gas-envelope constraint can partition into smaller empty batches. Opaque `DeploymentFailed`, unclassified/source/provider-clamp errors, byte-cap refusals and near-cap consumption do not authorize that search. Core/validator/registry/hook invariant errors stop planning.
924
+ - Staged: prerequisites, `beginLaunch(Staged)`, greedily packed contiguous empty `prepareMarkets` batches, then one `activateLaunch`. A packed measurement failure using at least 95% of its given gas splits only that batch; low-gas semantic errors, byte caps and unlocated provider failures do not justify a split. Proof may cover only a prefix, with the unproved suffix explicitly deferred.
817
925
  - Activation cannot split. If mint/lock/all buys/opening cannot fit, staged is also refused. No position/buy/minimum is omitted to manufacture success.
818
926
 
819
927
  No automatic atomic-to-staged fallback exists. Obtain separate consent to review the same commitment as staged. Both venues use token transfer restrictions plus activation-time canonical opening-state checks, not a pool gate. Manipulated opening price or preactivation liquidity fails verification; the token stays inactive and the launch remains Ready/cancellable. Failed activation rolls back every mint, seal, buy and opening together.
820
928
 
821
929
  ## Execution constraints and stateful simulation
822
930
 
823
- Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit`, `maxCalldataBytes` and
824
- `maxSimulationGas` tighten admission when supplied. Missing policy remains explicit in
825
- `limits.unknownExecutionConstraints`/`unknownConstraints`; it does not reject an otherwise
826
- proved exact sequence or invent a provider/account cap. No policy service is required.
931
+ Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit` and `maxCalldataBytes`
932
+ tighten admission. `maxSimulationGas` sets the aggregate used-gas proof-window
933
+ budget (default 50M on 4663, unknown on other chains). Missing policy stays explicit
934
+ in `limits.unknownExecutionConstraints`/`unknownConstraints`; no policy service is required.
827
935
  A `LifecycleLimitSource` callback receives the canonical chain/account/core/block context.
828
936
  Any supplied provenance must match it; stale/mismatched/malformed facts or a failed supplied
829
937
  resolver reject rather than disappearing into optional uncertainty. Gas caps are positive
@@ -831,7 +939,9 @@ exact uint64 `bigint`; calldata is a positive safe integer byte count.
831
939
  Reviewed gas envelopes are positive uint64 too; zero-metering observations cannot admit
832
940
  a zero-gas transaction. Headroom calculations retain wide exact bigint intermediates.
833
941
 
834
- Headroom defaults to 1,500 bps, bounded 0–10,000. Generic EVM admission uses the pinned
942
+ Headroom defaults to 1,500 bps, bounded 0–10,000; it clamps to current legal ceilings
943
+ instead of rejecting a fitting measured requirement. HMM V2 adds the forwarding
944
+ target documented above once on atomic/activation. Generic EVM admission uses the pinned
835
945
  bounded header and supplied total-envelope restrictions plus actual validated RPC proof.
836
946
  It reports an absent independent per-transaction cutoff honestly, without importing a
837
947
  universal Ethereum cutoff. `executionGasCeiling` and `transactionGasCeiling` are equal on
@@ -844,8 +954,8 @@ carries that successfully replayed ceiling, never a smaller unproved envelope.
844
954
  Replay source, HTTP and malformed-response failures remain provisional with
845
955
  `executionProof: "unavailable"` and do not retry economic execution. `AbortError`
846
956
  propagates unchanged, including cancellation during supplied policy and Nitro getter
847
- reads. A recognized execution refusal may discover at most one genuinely larger
848
- validated envelope within the same legal compute/total limits. Without returned
957
+ reads. Only explicit genuine native out-of-gas evidence may discover at most one
958
+ larger validated envelope within the same legal compute/total limits. Without returned
849
959
  failing-call evidence, `failedTransactionId` stays absent; an opaque RPC error does
850
960
  not invent a failing transaction or authorize preparation partitioning.
851
961
  Returned failures retain the actual exact-replay prefix and its first failing
@@ -883,10 +993,10 @@ The buffered compute-discovery envelope plus buffered poster budget is carried i
883
993
  exact validated replay; an approximate poster quote is never subtracted from total
884
994
  gas use to certify exact compute fit.
885
995
  Measurement waits for successful capability and candidate-specific poster evidence,
886
- then uses the legal complete compute-plus-poster envelope. Near-cap gas consumption
887
- does not diagnose OOG, constructor failure or collision. Unsupported/transport
888
- evidence remains unavailable, and only a recognized execution-envelope refusal
889
- can trigger bounded envelope discovery.
996
+ then uses the legal complete compute-plus-poster envelope. A packed preparation
997
+ failure consuming at least 95% may invalidate its cost estimate without claiming
998
+ its selector diagnoses OOG. Unsupported/transport evidence remains unavailable,
999
+ except an observed aggregate-budget exhaustion can preserve a successful prefix.
890
1000
 
891
1001
  A separate pinned validated simulation probes all three ArbOS/version/getter values
892
1002
  against the canonical observations. Only that isolated capability probe temporarily
@@ -909,13 +1019,13 @@ does not manufacture an all-in estimate. All observations and limits refresh for
909
1019
  For initial construction, the exact legacy gas-price envelope is the greater of
910
1020
  the fresh RPC recommendation and twice the pinned base fee. This avoids
911
1021
  underpriced submission when `eth_gasPrice` lags the block base fee. Reviewed
912
- envelopes retain their exact gas/price only after fresh full-sequence measurement,
913
- native validated replay, current minimum headroom and affordability checks.
1022
+ envelopes retain exact gas/price through direct immediate native validated replay
1023
+ and immediate affordability, without repeating measurement or applying new padding.
914
1024
  The held price need not equal a new recommendation or twice the current base fee;
915
1025
  natural child fees and the actual submission estimate must accept it. Replay,
916
1026
  affordability and submission use that same price, without a base-fee override.
917
- A known aggregate budget whose legal minimum already exceeds its ceiling refuses
918
- before capability probes or poster work; equality is allowed. A definitive returned
1027
+ An aggregate budget selects the longest fitting estimated prefix; only when even
1028
+ the immediate estimate does not fit is no proof possible. A definitive returned
919
1029
  failure from the final exact replay skips a later payer-balance lookup, while
920
1030
  retaining fee/estimate validation and final canonical checks. Successful replay
921
1031
  still requires current actual-balance affordability.
@@ -947,14 +1057,15 @@ Simulation and `next.admission` carry flat, independent proof outcomes:
947
1057
 
948
1058
  | Field | Values | Scope |
949
1059
  | --- | --- | --- |
950
- | `executionProof` | `"proved"`, `"failed"`, `"unavailable"` | Complete stateful exact-envelope execution and postconditions, never permissive measurement alone. |
1060
+ | `executionProof` | `"proved"`, `"failed"`, `"unavailable"` | Stateful exact-envelope execution/postconditions for the proven prefix (or the immediate reviewed step), never measurement alone or an unproved suffix. |
951
1061
  | `protocolFit` | `"proved"`, `"failed"`, `"unknown"` | Applicable proven protocol and known tightening restrictions. Missing optional policy remains separately disclosed. |
952
1062
  | `transportPreflight` | `"not-requested"`, `"passed"`, `"failed"` | Immediate exact next-transaction acceptance estimate on the supplied submission RPC. |
953
1063
 
954
- `admitted` means the current exact sequence is proved to fit and affordable; it is
955
- not guaranteed wallet submission or future execution. Admission reuses simulation
956
- `blockNumber`, `blockHash`, `account`, `chainId` and `limits`. Plans never preflight
957
- future dependent transactions against state that does not exist.
1064
+ `admitted` means the proven prefix fits and is affordable, not that deferred
1065
+ transactions have executed or that eventual activation is guaranteed. Always
1066
+ inspect `simulation.deferredTransactionIds`. Admission reuses `blockNumber`,
1067
+ `blockHash`, `account`, `chainId` and `limits`; signing uses only fresh build-next
1068
+ admission. Plans never preflight future steps independently against nonexistent state.
958
1069
 
959
1070
  ```ts
960
1071
  const planned = await planLaunch({ client, account: plan.creator, plan, mode: "atomic" });
@@ -35,3 +35,7 @@ NFT_BASE_URI=
35
35
  # EXAMPLE_ACCOUNT_GAS_CAP=
36
36
  # EXAMPLE_MAX_CALLDATA_BYTES=
37
37
  # EXAMPLE_HEADROOM_BPS=1500
38
+ #
39
+ # Robinhood aggregate simulation gas-used budget defaults to 50M. Override only for
40
+ # a provider supporting that budget; buy-output calibration needs activation coverage.
41
+ # EXAMPLE_SIMULATION_GAS_CAP=100000000
@@ -1,15 +1,17 @@
1
1
  # Examples
2
2
 
3
- The launch examples use the public `@black-market/sdk` 0.9.0 package and viem.
3
+ The launch examples use the public `@black-market/sdk` 0.11.0 package and viem.
4
4
  Build this checkout before running its examples; in a consumer project install
5
- `@black-market/sdk@0.8.0` or later for the `positionGaps` and recovery APIs.
5
+ `@black-market/sdk@0.11.0` for current gas packing and proof-coverage semantics.
6
6
  The default chain-4663 launch cases retain
7
7
  the October8 mined fixed pool-bound V4 config6/V2 and canonical Abyss config1 deployment.
8
8
  The SDK additionally knows the October11 zero-author-royalty Dynamic Fee Hook;
9
9
  its registration does not change the fixed cases' selection or fee schedule.
10
- HMM Fixed/Dynamic are additional October11 presets; their required typed launch
11
- tail and defaults are demonstrated by `hmm-launch-config.ts`. Existing fixed
12
- cases are intentionally unchanged. See the HMM section in the lifecycle guide.
10
+ HMM Fixed/Dynamic V2 are additional admitted October17 presets; their required
11
+ 512-byte typed launch tail and explicit bid/reference guards are demonstrated by
12
+ `hmm-launch-config.ts`. The generic HMM profile keys now select V2 only.
13
+ Existing fixed cases are intentionally unchanged. See the lifecycle guide for
14
+ the breaking migration, per-swap funding and fee-owner configuration/pause ABIs.
13
15
  Historical October5 config5 evidence is not relabeled as these graphs. Discovery
14
16
  is read-only; fixed launch examples default to an unsigned dry run. Only
15
17
  `--broadcast` (or deliberate `--resume` continuation) authorizes real writes.
@@ -22,7 +24,7 @@ examples; their relative support imports use explicit `.ts` extensions for Node
22
24
  | Script | Behavior |
23
25
  | --- | --- |
24
26
  | `quickstart.ts` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
25
- | `hmm-launch-config.ts` | Pure HMM fixed/dynamic config construction with typed defaults and an automatically appended launch tail; no RPC, signatures or writes. |
27
+ | `hmm-launch-config.ts` | Pure HMM V2 fixed/dynamic config construction with caller-chosen bid/reference guards and an automatically appended 512-byte launch tail; no RPC, signatures or writes. |
26
28
  | `launch.ts` | Reviews/reconstructs an explicit saved plan and selected atomic/staged mode; optional offchain config6/V2 salt mining. Prints simulation, progress, and an admitted unsigned next transaction when evidence permits. |
27
29
  | `generate-lifecycle-commitment-fixture.ts` | Frozen independent historical config4/Abyss ABI bytes/hash/identity vector. Its pre-cutover allocations are not an executable 0.7.1 plan. |
28
30
  | `launch-lifecycle-smoke.ts` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
@@ -71,6 +73,18 @@ generic EVM, not as a Nitro metering substitute. Unsigned review reports
71
73
  RPC to build-next. See the
72
74
  [lifecycle guide](../docs/launch-lifecycle.md#execution-constraints-and-stateful-simulation).
73
75
 
76
+ Robinhood defaults to a 50M aggregate simulation gas-used budget. Inspect
77
+ `simulation.deferredTransactionIds`: admitted/proved means the proven prefix,
78
+ not every future transaction or eventual activation. Deferred commands have no
79
+ gas/price/estimate/admission; obtain each fresh immediate envelope through
80
+ `buildNextTransaction` after canonical progress advances. Reviewed envelopes are
81
+ replayed directly, without measuring/replaying the suffix again. The saved-plan
82
+ CLI prints proof coverage and never signs. Override `limits.maxSimulationGas` only
83
+ for a provider that supports the selected budget. Examples requiring actual
84
+ activation outputs for `buySlippageBps` or economic review refuse if activation is
85
+ deferred; use a suitably higher-budget provider rather than inventing buy outputs.
86
+
87
+
74
88
  For a real new graph, create the saved plan using `readLifecycleProfiles` with its
75
89
  explicit chain/core and admitted pool-bound config6 profile. Supply that graph's RPC
76
90
  to `launch.ts`; do not substitute the historical known preset. Applications may use
@@ -379,6 +393,13 @@ to tighten the complete transaction envelope: `EXAMPLE_CHAIN_GAS_CAP`,
379
393
  restrictions, not invented provider/account assurances or admission bypasses.
380
394
  Poster allocation is already inside Nitro gas/affordability and is not charged twice.
381
395
 
396
+ Robinhood's separate aggregate simulation gas-used budget defaults to **50M**.
397
+ `EXAMPLE_SIMULATION_GAS_CAP` overrides that budget (positive decimal gas) for
398
+ providers supporting more or less. It does not change per-transaction compute
399
+ capacity. Multi-step examples requiring full activation outputs for buy protection
400
+ and economic review need a provider/budget covering activation, or refuse before
401
+ signing; do not raise the setting beyond the provider's actual supported budget.
402
+
382
403
  ### Evidence and failure recovery
383
404
 
384
405
  Each dry run or broadcast automatically creates `launch-results/<timestamp-case-random>/`;
@@ -10,7 +10,10 @@ const tokenBudget = 1000000n * 10n ** 18n;
10
10
  for (const key of [KnownLifecycleProfile.V4HmmFixedPool, KnownLifecycleProfile.V4HmmDynamicPool]) {
11
11
  const preset = getKnownLifecycleProfile({ ...identity, key })!;
12
12
  const envelope = preset.profile.envelope!;
13
- const hmmLaunchConfig = defaultHmmLaunchConfig({ tokenBudget, quoteAsset: "USDG", quoteDecimals: 6 });
13
+ // Illustrative caller-chosen guards: at most 100 six-decimal USDG
14
+ // of bid principal, and no ask below/bid above the rounded oracle reference.
15
+ const hmmLaunchConfig = defaultHmmLaunchConfig({ tokenBudget, quoteAsset: "USDG", quoteDecimals: 6,
16
+ maxBidQuote: 100n * 10n ** 6n, referenceDeviation: 0 });
14
17
  // Optional explicit choices: share 2500/5000/10000 bps; decay off/259200 (72h).
15
18
  const config = encodePoolBoundV4LifecycleMarketConfig({
16
19
  version: 6, lpFeePips: 0, tickSpacing: 60, sqrtPriceX96: 1n << 96n,
@@ -540,6 +540,7 @@ export async function readExampleConfiguration(sdk, redactor, env = process.env)
540
540
  chainTransactionGasLimit: gasCap("EXAMPLE_CHAIN_GAS_CAP"),
541
541
  rpcTransactionGasLimit: gasCap("EXAMPLE_RPC_GAS_CAP"),
542
542
  accountTransactionGasLimit: gasCap("EXAMPLE_ACCOUNT_GAS_CAP"),
543
+ rpcTotalSimulationGasLimit: gasCap("EXAMPLE_SIMULATION_GAS_CAP"),
543
544
  maxCalldataBytes: integer("EXAMPLE_MAX_CALLDATA_BYTES", undefined, 1, Number.MAX_SAFE_INTEGER),
544
545
  headroomBps: integer("EXAMPLE_HEADROOM_BPS", 1500, 0, 10000),
545
546
  provenance: { scope: "user-ceilings", note: "Optional local tightening restrictions, not verified provider or account limits" },
@@ -477,6 +477,7 @@ function limitSource(fixture, artifacts) {
477
477
  chainGasLimit: policy.chainTransactionGasLimit === undefined ? undefined : BigInt(policy.chainTransactionGasLimit),
478
478
  rpcGasLimit: policy.rpcTransactionGasLimit === undefined ? undefined : BigInt(policy.rpcTransactionGasLimit),
479
479
  accountGasLimit: policy.accountTransactionGasLimit === undefined ? undefined : BigInt(policy.accountTransactionGasLimit),
480
+ maxSimulationGas: policy.rpcTotalSimulationGasLimit === undefined ? undefined : BigInt(policy.rpcTotalSimulationGasLimit),
480
481
  maxCalldataBytes: policy.maxCalldataBytes, headroomBps: policy.headroomBps,
481
482
  };
482
483
  artifacts.event("execution-limits", { limits, provenance: policy.provenance });
@@ -30,6 +30,7 @@ const options = { client, account: plan.creator, plan, mode, limits, fork, recei
30
30
  const planned = args.includes("--mine")
31
31
  ? await prepareAndPlanLifecycleLaunch({ ...options, onProgress: ({ marketIndex, attempts }) => console.error("salt mining", marketIndex, attempts.toString()) })
32
32
  : await planLaunch(options);
33
+ console.error("Proof coverage:", planned.simulation.steps.length, "steps; deferred:", planned.simulation.deferredTransactionIds);
33
34
  const progress = await readLaunchProgress({ client, planned, receipts, confirmations });
34
35
  const next = planned.simulation.admitted ? await buildNextTransaction({ client, planned, limits, fork, receipts, confirmations }) : undefined;
35
36
  console.log(JSON.stringify({ plan: JSON.parse(serializeLaunchPlan(planned.plan)), mode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@black-market/sdk",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "TypeScript SDK for Abyss token launches, swaps, and lending.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  "lint": "tsc -p tsconfig.json --noEmit",
44
44
  "prepublishOnly": "pnpm build",
45
45
  "test": "pnpm test:unit",
46
- "test:unit": "pnpm build && node --test test/*.test.mjs",
46
+ "test:unit": "pnpm build && node --import ./test/register-typescript.mjs --test test/*.test.mjs",
47
47
  "test:api": "pnpm build && node --test test/integration/launch-api.read.test.mjs",
48
48
  "test:api:write": "pnpm build && node --test test/integration/launch-api.sessions.test.mjs",
49
49
  "typecheck": "tsc -p tsconfig.json --noEmit"
@@ -5,6 +5,7 @@ import {
5
5
  profileRegistrationV1Components, profileTopologyV1Components, launchEnvelopeV2Components, sourceTermsV3Components,
6
6
  } from "./schema.js";
7
7
  import { poolBoundHookParametersV1Components, poolBoundHookParametersV2Components, v4LifecycleMarketComponents } from "./markets.js";
8
+ export { hmmLiquidityManagerV2Abi, hmmFeeCollectorV2Abi, hmmFeeCollectorFactoryV2Abi, hmmFixedHookV2Abi, hmmDynamicHookV2Abi } from "./hmm-abi.js";
8
9
 
9
10
  const planInput = { name: "plan", type: "tuple", components: launchPlanV1Components } as const;
10
11
  export const launchLifecycleAbi = [
@@ -43,6 +43,7 @@ export function validateBuySlippageBps(bps: number): void {
43
43
  export function protectOrderedBuyMinimums(planned: PlannedLaunch, bps: number): LaunchPlanV1 {
44
44
  validateBuySlippageBps(bps);
45
45
  const { simulation, plan } = planned;
46
+ if (simulation.deferredTransactionIds.length !== 0) throw new LifecyclePlanningError("LAUNCH_DIAGNOSTIC_FAILED", "Buy slippage calibration requires actual activation outputs beyond the proven RPC prefix; use a higher aggregate simulation cap/provider or preserve already committed minima without buySlippageBps", simulation);
46
47
  if (simulation.confidence !== "stateful" || simulation.backend === "unavailable" || simulation.steps.length !== planned.transactions.length || simulation.steps.some((step, index) => !step.success || step.transactionId !== planned.transactions[index]?.id)) throw new LifecyclePlanningError("LAUNCH_DIAGNOSTIC_FAILED", simulation.reason ?? "The complete diagnostic launch sequence did not execute successfully", simulation);
47
48
  const activation = planned.transactions.find((transaction) => transaction.kind === "atomic" || transaction.kind === "activate");
48
49
  const step = simulation.steps.find((candidate) => candidate.transactionId === activation?.id);