@black-market/sdk 0.15.0 → 0.15.1

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 (93) hide show
  1. package/README.md +9 -8
  2. package/dist/lifecycle/auto-compound.d.ts +21 -0
  3. package/dist/lifecycle/auto-compound.d.ts.map +1 -0
  4. package/dist/lifecycle/auto-compound.js +34 -0
  5. package/dist/lifecycle/auto-compound.js.map +1 -0
  6. package/dist/lifecycle/calibration.d.ts +2 -4
  7. package/dist/lifecycle/calibration.d.ts.map +1 -1
  8. package/dist/lifecycle/calibration.js +1 -26
  9. package/dist/lifecycle/calibration.js.map +1 -1
  10. package/dist/lifecycle/deployments/auto-compound-dynamic-pool-v1-20261028.d.ts +73 -0
  11. package/dist/lifecycle/deployments/auto-compound-dynamic-pool-v1-20261028.d.ts.map +1 -0
  12. package/dist/lifecycle/deployments/auto-compound-dynamic-pool-v1-20261028.js +75 -0
  13. package/dist/lifecycle/deployments/auto-compound-dynamic-pool-v1-20261028.js.map +1 -0
  14. package/dist/lifecycle/deployments/auto-compound-static-pool-v1-20261028.d.ts +73 -0
  15. package/dist/lifecycle/deployments/auto-compound-static-pool-v1-20261028.d.ts.map +1 -0
  16. package/dist/lifecycle/deployments/auto-compound-static-pool-v1-20261028.js +75 -0
  17. package/dist/lifecycle/deployments/auto-compound-static-pool-v1-20261028.js.map +1 -0
  18. package/dist/lifecycle/gas-profile.d.ts +17 -13
  19. package/dist/lifecycle/gas-profile.d.ts.map +1 -1
  20. package/dist/lifecycle/gas-profile.js +125 -115
  21. package/dist/lifecycle/gas-profile.js.map +1 -1
  22. package/dist/lifecycle/index.d.ts +4 -4
  23. package/dist/lifecycle/index.d.ts.map +1 -1
  24. package/dist/lifecycle/index.js +4 -4
  25. package/dist/lifecycle/index.js.map +1 -1
  26. package/dist/lifecycle/markets.d.ts +2 -0
  27. package/dist/lifecycle/markets.d.ts.map +1 -1
  28. package/dist/lifecycle/markets.js +30 -3
  29. package/dist/lifecycle/markets.js.map +1 -1
  30. package/dist/lifecycle/opening-buys.js +1 -1
  31. package/dist/lifecycle/opening-buys.js.map +1 -1
  32. package/dist/lifecycle/planner.d.ts +6 -9
  33. package/dist/lifecycle/planner.d.ts.map +1 -1
  34. package/dist/lifecycle/planner.js +102 -207
  35. package/dist/lifecycle/planner.js.map +1 -1
  36. package/dist/lifecycle/presets.d.ts +7 -3
  37. package/dist/lifecycle/presets.d.ts.map +1 -1
  38. package/dist/lifecycle/presets.js +10 -1
  39. package/dist/lifecycle/presets.js.map +1 -1
  40. package/dist/lifecycle/rpc.d.ts +3 -13
  41. package/dist/lifecycle/rpc.d.ts.map +1 -1
  42. package/dist/lifecycle/rpc.js +11 -37
  43. package/dist/lifecycle/rpc.js.map +1 -1
  44. package/dist/lifecycle/snapshot.d.ts.map +1 -1
  45. package/dist/lifecycle/snapshot.js +1 -2
  46. package/dist/lifecycle/snapshot.js.map +1 -1
  47. package/dist/lifecycle/transactions.d.ts +10 -3
  48. package/dist/lifecycle/transactions.d.ts.map +1 -1
  49. package/dist/lifecycle/transactions.js +40 -10
  50. package/dist/lifecycle/transactions.js.map +1 -1
  51. package/dist/lifecycle/types.d.ts +32 -107
  52. package/dist/lifecycle/types.d.ts.map +1 -1
  53. package/dist/lifecycle/types.js +3 -3
  54. package/dist/lifecycle/types.js.map +1 -1
  55. package/dist/lifecycle/ufg.d.ts +1 -1
  56. package/dist/lifecycle/ufg.d.ts.map +1 -1
  57. package/dist/lifecycle/ufg.js +1 -1
  58. package/dist/lifecycle/ufg.js.map +1 -1
  59. package/docs/launch-lifecycle.md +43 -0
  60. package/docs/lifecycle-gas-profiles.md +1 -1
  61. package/docs/reference.md +56 -2
  62. package/examples/.env.example +0 -3
  63. package/examples/README.md +10 -10
  64. package/examples/launch-example-support.ts +4 -9
  65. package/examples/launch-example.ts +12 -28
  66. package/examples/launch-lifecycle-smoke.ts +10 -22
  67. package/examples/launch.ts +8 -11
  68. package/package.json +1 -1
  69. package/src/lifecycle/auto-compound.ts +38 -0
  70. package/src/lifecycle/calibration.ts +3 -23
  71. package/src/lifecycle/deployments/auto-compound-dynamic-pool-v1-20261028.ts +77 -0
  72. package/src/lifecycle/deployments/auto-compound-static-pool-v1-20261028.ts +77 -0
  73. package/src/lifecycle/gas-profile.ts +117 -106
  74. package/src/lifecycle/index.ts +4 -4
  75. package/src/lifecycle/markets.ts +25 -3
  76. package/src/lifecycle/opening-buys.ts +1 -1
  77. package/src/lifecycle/planner.ts +98 -190
  78. package/src/lifecycle/presets.ts +10 -1
  79. package/src/lifecycle/rpc.ts +10 -32
  80. package/src/lifecycle/snapshot.ts +1 -2
  81. package/src/lifecycle/transactions.ts +39 -9
  82. package/src/lifecycle/types.ts +38 -87
  83. package/src/lifecycle/ufg.ts +1 -1
  84. package/dist/lifecycle/fork.d.ts +0 -15
  85. package/dist/lifecycle/fork.d.ts.map +0 -1
  86. package/dist/lifecycle/fork.js +0 -36
  87. package/dist/lifecycle/fork.js.map +0 -1
  88. package/dist/lifecycle/simulation.d.ts +0 -17
  89. package/dist/lifecycle/simulation.d.ts.map +0 -1
  90. package/dist/lifecycle/simulation.js +0 -605
  91. package/dist/lifecycle/simulation.js.map +0 -1
  92. package/src/lifecycle/fork.ts +0 -36
  93. package/src/lifecycle/simulation.ts +0 -543
@@ -11,6 +11,9 @@ import { HMM_FIXED_PROFILE_ID, HMM_DYNAMIC_PROFILE_ID, isHmmProfile } from "./hm
11
11
  import { ufgFixedEnvelope, ufgFixedAdapter, ufgFixedRegistration } from "./deployments/ufg-fixed-pool-20261021.js";
12
12
  import { ufgDynamicEnvelope, ufgDynamicAdapter, ufgDynamicRegistration } from "./deployments/ufg-dynamic-pool-20261021.js";
13
13
  import { UFG_FIXED_PROFILE_ID, UFG_DYNAMIC_PROFILE_ID } from "./ufg-config.js";
14
+ import { autoCompoundStaticEnvelope, autoCompoundStaticAdapter, autoCompoundStaticRegistration, autoCompoundStaticCreationCode } from "./deployments/auto-compound-static-pool-v1-20261028.js";
15
+ import { autoCompoundDynamicEnvelope, autoCompoundDynamicAdapter, autoCompoundDynamicRegistration, autoCompoundDynamicCreationCode } from "./deployments/auto-compound-dynamic-pool-v1-20261028.js";
16
+ import { AUTO_COMPOUND_STATIC_V1_PROFILE_ID, AUTO_COMPOUND_DYNAMIC_V1_PROFILE_ID } from "./auto-compound.js";
14
17
 
15
18
  export enum KnownLifecycleProfile {
16
19
  Abyss0 = "abyss-0",
@@ -23,6 +26,8 @@ export enum KnownLifecycleProfile {
23
26
  V4HmmDynamicPool = "v4-hmm-dynamic-pool",
24
27
  V4UfgFixedPool = "v4-ufg-fixed-pool",
25
28
  V4UfgDynamicPool = "v4-ufg-dynamic-pool",
29
+ V4AutoCompoundStaticPool = "v4-auto-compound-static-pool",
30
+ V4AutoCompoundDynamicPool = "v4-auto-compound-dynamic-pool",
26
31
  }
27
32
 
28
33
  export enum KnownLifecycleHook {
@@ -30,6 +35,8 @@ export enum KnownLifecycleHook {
30
35
  DynamicFeePoolV1 = "dynamic-fee-pool-v1",
31
36
  HmmFixedPoolV2 = "hmm-fixed-pool-v2",
32
37
  HmmDynamicPoolV2 = "hmm-dynamic-pool-v2",
38
+ AutoCompoundStaticV1 = "auto-compound-static-v1",
39
+ AutoCompoundDynamicV1 = "auto-compound-dynamic-v1",
33
40
  }
34
41
 
35
42
  Object.freeze(KnownLifecycleProfile);
@@ -351,6 +358,8 @@ const knownDeployment: LifecycleDeploymentPreset = Object.freeze({
351
358
  poolBoundPreset(KnownLifecycleProfile.V4HmmDynamicPool, HMM_DYNAMIC_PROFILE_ID, hmmDynamicEnvelope, hmmDynamicAdapter, hmmDynamicRegistration, hmmDynamicCreationCode),
352
359
  poolBoundPreset(KnownLifecycleProfile.V4UfgFixedPool, UFG_FIXED_PROFILE_ID, ufgFixedEnvelope, ufgFixedAdapter, ufgFixedRegistration, fixedFeePoolHookV1CreationCode),
353
360
  poolBoundPreset(KnownLifecycleProfile.V4UfgDynamicPool, UFG_DYNAMIC_PROFILE_ID, ufgDynamicEnvelope, ufgDynamicAdapter, ufgDynamicRegistration, dynamicFeePoolHookV1CreationCode),
361
+ poolBoundPreset(KnownLifecycleProfile.V4AutoCompoundStaticPool, AUTO_COMPOUND_STATIC_V1_PROFILE_ID, autoCompoundStaticEnvelope, autoCompoundStaticAdapter, autoCompoundStaticRegistration, autoCompoundStaticCreationCode),
362
+ poolBoundPreset(KnownLifecycleProfile.V4AutoCompoundDynamicPool, AUTO_COMPOUND_DYNAMIC_V1_PROFILE_ID, autoCompoundDynamicEnvelope, autoCompoundDynamicAdapter, autoCompoundDynamicRegistration, autoCompoundDynamicCreationCode),
354
363
  ]),
355
364
  provenance: Object.freeze({ sourceCommit: "e174ce695c7010f50ca9211b07b9f178c990beac", deploymentBlock: 82880546n }),
356
365
  });
@@ -380,7 +389,7 @@ export function getKnownLifecycleProfile(options: KnownLifecycleDeploymentIdenti
380
389
  return undefined;
381
390
  }
382
391
 
383
- /** Stable, frozen order: Abyss variants, fixed/dynamic V4, HMM, then UFG fixed/dynamic. */
392
+ /** Stable, frozen order: Abyss, fixed/dynamic V4, HMM, UFG, then auto-compounding. */
384
393
  export function listKnownLifecycleProfiles(options: KnownLifecycleDeploymentIdentity): readonly LifecycleProfilePreset[] {
385
394
  return getKnownLifecycleDeployment(options)?.profiles ?? noProfiles;
386
395
  }
@@ -22,8 +22,8 @@ type IndependentRead = { params: readonly unknown[]; resolve: (value: unknown) =
22
22
  const lifecycleReadConcurrency = 8;
23
23
  const diagnosticRpcMethods: Record<string, true> = {
24
24
  eth_chainId: true, eth_getBlockByNumber: true, eth_getBlockByHash: true, eth_getCode: true,
25
- eth_getBalance: true, eth_call: true, eth_estimateGas: true, eth_gasPrice: true,
26
- eth_simulateV1: true, eth_getTransactionCount: true, eth_getTransactionReceipt: true, eth_getTransactionByHash: true,
25
+ eth_getBalance: true, eth_call: true, eth_gasPrice: true,
26
+ eth_getTransactionReceipt: true, eth_getTransactionByHash: true,
27
27
  };
28
28
 
29
29
  type SessionReadGroup = {
@@ -70,7 +70,7 @@ class SessionLifecycleCache implements LifecycleSessionCache {
70
70
  }
71
71
  }
72
72
 
73
- /** Opt-in pinned read reuse; client-bound identity/capability facts are separate. */
73
+ /** Opt-in pinned read reuse; client-bound identity/deployment facts are separate. */
74
74
  export function createLifecycleSessionCache(): LifecycleSessionCache {
75
75
  return new SessionLifecycleCache();
76
76
  }
@@ -410,7 +410,7 @@ export function readLifecycleImmutable<T>(client: LifecycleRpcClient, key: strin
410
410
  return (client instanceof InvocationLifecycleClient ? client.immutableRead(key, work) : work()) as Promise<T>;
411
411
  }
412
412
 
413
- /** Successful deployment/backend observations live for the caller's session, not one block. */
413
+ /** Successful deployment observations live for the caller's session, not one block. */
414
414
  export function lifecycleSessionRead<T>(client: LifecycleRpcClient, key: string, work: () => Promise<T>): Promise<T> {
415
415
  const source = lifecycleSourceClient(client);
416
416
  const owner = source.sessionCache ?? source;
@@ -524,9 +524,7 @@ export async function readLifecycleProfileTopology(client: LifecycleRpcClient, r
524
524
  if (topology.hookTopology !== 0 && topology.hookTopology !== 1 && topology.hookTopology !== 2) throw new LifecyclePlanningError("INVALID_RPC_RESPONSE", "Registry returned an unsupported hook topology");
525
525
  return { ...topology, hookTopology: topology.hookTopology };
526
526
  }
527
- export const nitroArbSys = "0x0000000000000000000000000000000000000064";
528
527
  export const nitroGasInfo = "0x000000000000000000000000000000000000006c";
529
- export const nitroArbSysAbi = parseAbi(["function arbOSVersion() view returns (uint256)"]);
530
528
  export const nitroGasInfoAbi = parseAbi([
531
529
  // Transaction ceilings are release preset metadata, not guard-only getter reads.
532
530
  "function getPricesInWei() view returns (uint256,uint256,uint256,uint256,uint256,uint256)",
@@ -534,7 +532,7 @@ export const nitroGasInfoAbi = parseAbi([
534
532
  export type LifecycleNitroPrices = readonly [bigint, bigint, bigint, bigint, bigint, bigint];
535
533
  const maxUint64 = (1n << 64n) - 1n;
536
534
 
537
- /** Seeded by the planning aggregate; standalone simulation batches this with limits. */
535
+ /** Seeded by the explicitly pinned planning aggregate. */
538
536
  export function readNitroPrices(client: LifecycleRpcClient, block: LifecycleBlock): Promise<LifecycleNitroPrices> {
539
537
  return readLifecycleContract(client, nitroGasInfo, nitroGasInfoAbi, "getPricesInWei", [], block, undefined, true, true);
540
538
  }
@@ -551,12 +549,6 @@ export function nitroPosterGasBound(transaction: Pick<LifecycleTransaction, "dat
551
549
  return { posterGas: 2n * ((feeBound + prices[5] - 1n) / prices[5]), feeBound };
552
550
  }
553
551
 
554
- async function readNitroScalar(context: LifecycleLimitContext, to: Address, abi: Abi, functionName: string): Promise<bigint> {
555
- const data = encodeFunctionData({ abi, functionName });
556
- const result = rpcHex(await lifecycleIndependentRpc(context.client, [{ to, data }, toHex(context.block.number)], context.block, true), functionName);
557
- if (result.length !== 66) throw new LifecyclePlanningError("INVALID_RPC_RESPONSE", `${functionName} must return exactly one ABI word`);
558
- return decodeFunctionResult({ abi, functionName, data: result }) as bigint;
559
- }
560
552
 
561
553
  export type LifecycleLimitObservation = {
562
554
  limits: ResolvedLifecycleLimits;
@@ -591,7 +583,7 @@ async function resolveLifecycleLimitsFresh(context: LifecycleLimitContext, sourc
591
583
  };
592
584
  const headroomBps = configuration.headroomBps === undefined ? 1500 : configuration.headroomBps;
593
585
  if (!Number.isSafeInteger(headroomBps) || headroomBps < 0 || headroomBps > 10000) throw new LifecyclePlanningError("INVALID_LIMITS", "Headroom must be between zero and 10000 basis points");
594
- for (const limit of [context.block.gasLimit, configuration.chainGasLimit, configuration.rpcGasLimit, configuration.accountGasLimit, configuration.maxSimulationGas]) {
586
+ for (const limit of [context.block.gasLimit, configuration.chainGasLimit, configuration.rpcGasLimit, configuration.accountGasLimit]) {
595
587
  if (limit !== undefined && (typeof limit !== "bigint" || limit <= 0n || limit > maxUint64)) throw new LifecyclePlanningError("INVALID_LIMITS", "Gas caps must be positive exact uint64 bigint values");
596
588
  }
597
589
  if (configuration.maxCalldataBytes !== undefined && (!Number.isSafeInteger(configuration.maxCalldataBytes) || configuration.maxCalldataBytes <= 0)) throw new LifecyclePlanningError("INVALID_LIMITS", "Calldata cap must be a positive byte count");
@@ -604,37 +596,23 @@ async function resolveLifecycleLimitsFresh(context: LifecycleLimitContext, sourc
604
596
  throw new LifecyclePlanningError("LIMIT_CONTEXT_MISMATCH", "Supplied execution policy provenance differs from the canonical chain/account/core/block context");
605
597
  }
606
598
  const protocol = context.chainId === 4663n ? "nitro" : "evm";
607
- const maxSimulationGas = configuration.maxSimulationGas;
608
- let arbOSVersion: bigint | undefined;
609
- if (protocol === "nitro") {
610
- try {
611
- const rawVersion = await readNitroScalar(context, nitroArbSys, nitroArbSysAbi, "arbOSVersion");
612
- // ArbSys alone adds 55 to the logical Nitro ArbOS version.
613
- if (typeof rawVersion !== "bigint" || rawVersion < 105n) throw new Error("ArbOS version 50 or newer is required (ArbSys raw version >= 105)");
614
- arbOSVersion = rawVersion - 55n;
615
- } catch (failure) {
616
- if (failure instanceof Error && failure.name === "AbortError") throw failure;
617
- throw new LifecyclePlanningError("NITRO_LIMITS_UNAVAILABLE", `Pinned Nitro version could not be established: ${lifecycleFailureReason(failure)}`);
618
- }
619
- if (configuration.estimateDataFee !== undefined) throw new LifecyclePlanningError("INVALID_LIMITS", "Nitro poster fees are already included in gas; an external data-fee estimator would double-charge them");
620
- }
599
+ if (protocol === "nitro" && configuration.estimateDataFee !== undefined) throw new LifecyclePlanningError("INVALID_LIMITS", "Nitro poster fees are already included in gas; an external data-fee estimator would double-charge them");
621
600
  const envelopeCaps = [configuration.chainGasLimit, configuration.rpcGasLimit, configuration.accountGasLimit].filter((limit): limit is bigint => limit !== undefined);
622
601
  if (protocol === "evm") envelopeCaps.push(context.block.gasLimit);
623
602
  const transactionGasCeiling = envelopeCaps.length === 0 ? undefined : envelopeCaps.reduce((minimum, limit) => limit < minimum ? limit : minimum);
624
603
  const executionGasCeiling = protocol === "nitro" ? ROBINHOOD_NATIVE_TRANSACTION_GAS_LIMIT : transactionGasCeiling ?? context.block.gasLimit;
625
604
  const unknownExecutionConstraints = [
626
- ...(protocol === "evm" && configuration.chainGasLimit === undefined ? ["Independent chain per-transaction execution cap is unknown; proof is bounded by the pinned header and validated backend"] : []),
605
+ ...(protocol === "evm" && configuration.chainGasLimit === undefined ? ["Independent chain per-transaction cap is unknown; the budget is bounded by the pinned header"] : []),
627
606
  ...(configuration.rpcGasLimit === undefined ? ["RPC transaction gas-envelope cap is unknown"] : []),
628
607
  ...(configuration.accountGasLimit === undefined ? ["Current account/wallet transaction gas-envelope cap is unknown"] : []),
629
608
  ...(configuration.maxCalldataBytes === undefined ? ["Applicable chain/account/RPC calldata byte cap is unknown"] : []),
630
- ...(maxSimulationGas === undefined ? ["RPC aggregate simulation gas cap is unknown"] : []),
631
609
  ];
632
610
  assertCurrent();
633
611
  return {
634
612
  configuration, assertCurrent,
635
613
  limits: Object.freeze({
636
- protocol, executionGasCeiling, transactionGasCeiling, arbOSVersion, headroomBps,
637
- maxCalldataBytes: configuration.maxCalldataBytes, maxSimulationGas,
614
+ protocol, executionGasCeiling, transactionGasCeiling, headroomBps,
615
+ maxCalldataBytes: configuration.maxCalldataBytes,
638
616
  blockGasLimit: context.block.gasLimit, chainGasLimit: configuration.chainGasLimit,
639
617
  rpcGasLimit: configuration.rpcGasLimit, accountGasLimit: configuration.accountGasLimit,
640
618
  unknownExecutionConstraints: Object.freeze(unknownExecutionConstraints),
@@ -5,7 +5,7 @@ import { getKnownLifecycleDeployment, type LifecycleDeploymentPreset } from "./p
5
5
  import { lifecycleTokenPredictionAbi } from "./progress.js";
6
6
  import { launchLensAbi, observeLifecycleLens, type LifecycleLensSnapshot } from "./lens.js";
7
7
  import { hashLaunchIdentity, LifecycleFundingKind, type LaunchPlanV1 } from "./schema.js";
8
- import { attestLifecycleMulticall, lifecycleRpc, nitroArbSys, nitroArbSysAbi, nitroGasInfo, nitroGasInfoAbi, readLifecycleBlock, readLifecycleChainId, rpcHex, seedLifecycleRead } from "./rpc.js";
8
+ import { attestLifecycleMulticall, lifecycleRpc, nitroGasInfo, nitroGasInfoAbi, readLifecycleBlock, readLifecycleChainId, rpcHex, seedLifecycleRead } from "./rpc.js";
9
9
  import { LifecyclePlanningError, type LifecycleBlock, type LifecycleRpcClient } from "./types.js";
10
10
  import { UFG_LAUNCH_PROXY_ADDRESS } from "./ufg-config.js";
11
11
 
@@ -36,7 +36,6 @@ export async function readLifecyclePlanningBlock(client: LifecycleRpcClient, pla
36
36
  if (escrow !== undefined) add(asset, lifecycleErc20Abi, "allowance", [account, escrow]);
37
37
  }
38
38
  }
39
- add(nitroArbSys, nitroArbSysAbi, "arbOSVersion", []);
40
39
  add(nitroGasInfo, nitroGasInfoAbi, "getPricesInWei", []);
41
40
  await attestLifecycleMulticall(client, block);
42
41
  const calls = reads.map((read) => ({ target: read.to, allowFailure: true, callData: encodeFunctionData({ abi: read.abi, functionName: read.functionName, args: read.args }) }));
@@ -3,27 +3,57 @@ import { launchLifecycleAbi } from "./abi.js";
3
3
  import { LifecycleFundingKind, LifecycleMode, type LaunchPlanV1 } from "./schema.js";
4
4
  import { LifecyclePlanningError, type BuildLaunchTransactionsOptions, type LifecycleTransaction } from "./types.js";
5
5
  import { assertLifecycleTokenAllocation } from "./allocations.js";
6
- import { HMM_V2_PREPARE_GAS } from "./presets.js";
7
- import { isHmmProfile } from "./hmm.js";
8
6
  import { ufgLaunchProxyV1Abi } from "./ufg-abi.js";
9
- import { UFG_LAUNCH_PROXY_ADDRESS } from "./ufg-config.js";
7
+ import { UFG_LAUNCH_PROXY_ADDRESS, isUfgProfile } from "./ufg-config.js";
8
+ import { decodeAbyssLifecycleMarketConfig, decodePoolBoundV4LifecycleMarketConfig, decodeV4LifecycleMarketConfig, isPoolBoundV4ConfigVersion } from "./markets.js";
9
+ import { isHmmProfile } from "./hmm.js";
10
10
  import type { UfgLaunchConfig } from "./ufg-config.js";
11
11
 
12
- const OTHER_MARKET_PREPARE_GAS = 16_000_000n;
12
+ // Native9,723,187 Abyss3 (0x679d…e77), fork32-position10,900,786;
13
+ // fork V4 fixed/dynamic8-position8,804,466; UFG9,896,176; native HMM8-position14,676,638 (0x459c…5b7).
14
+ const preparationCosts = {
15
+ abyss: { market: 9_800_000n, position: 70_000n },
16
+ v4: { market: 9_000_000n, position: 40_000n },
17
+ ufg: { market: 10_000_000n, position: 70_000n },
18
+ hmm: { market: 15_000_000n, position: 50_000n },
19
+ } as const;
20
+ export const LIFECYCLE_CAPACITY_PADDING_BPS = 2500;
21
+ /** Full single-market observations include call overhead. Add conservative full
22
+ * calldata/hash processing (16 intrinsic gas per nonzero byte plus8 for copying). */
23
+ export function preparationCalldataGas(data: `0x${string}`): bigint { return 24n * BigInt((data.length - 2) / 2); }
13
24
 
14
25
  export function preparationGasEstimate(plan: LaunchPlanV1, first: number, count: number): bigint {
15
26
  let gas = 0n;
16
- for (let index = first; index < first + count; index += 1) gas += isHmmProfile(plan.markets[index]!.profileId) ? HMM_V2_PREPARE_GAS : OTHER_MARKET_PREPARE_GAS;
27
+ for (let index = first; index < first + count; index += 1) {
28
+ const market = plan.markets[index]!;
29
+ const positions = market.configVersion === 1 ? decodeAbyssLifecycleMarketConfig(market.config).positions.length
30
+ : isPoolBoundV4ConfigVersion(market.configVersion) ? decodePoolBoundV4LifecycleMarketConfig(market.config, market.configVersion).positions.length
31
+ : decodeV4LifecycleMarketConfig(market.config).positions.length;
32
+ const cost = market.configVersion === 1 ? preparationCosts.abyss : isHmmProfile(market.profileId) ? preparationCosts.hmm
33
+ : isUfgProfile(market.profileId) ? preparationCosts.ufg : preparationCosts.v4;
34
+ gas += cost.market + cost.position * BigInt(positions - 1);
35
+ }
17
36
  return gas;
18
37
  }
19
38
 
20
- /** Contiguous cost packing preserves committed market order and recovery progress. */
21
- export function packPreparationBatches(plan: LaunchPlanV1, prepared: number, computeCap: bigint): number[] {
39
+ /** Contiguous deterministic packing with compute headroom. The caller reserves
40
+ * poster allocation separately from computeCap; neither resizes transaction gas. */
41
+ export function packPreparationBatches(plan: LaunchPlanV1, prepared: number, computeCap: bigint, headroomBps = 1500): number[] {
42
+ const data = buildLifecycleCommand(plan, { kind: "prepare", first: prepared, count: 1 }).data;
43
+ return packLifecyclePreparationBatches(plan, prepared, computeCap, headroomBps, preparationCalldataGas(data));
44
+ }
45
+
46
+ /** Internal path reuses the command already encoded for poster allocation. */
47
+ export function packLifecyclePreparationBatches(plan: LaunchPlanV1, prepared: number, computeCap: bigint, headroomBps: number, calldataGas: bigint): number[] {
48
+ if (!Number.isSafeInteger(headroomBps) || headroomBps < 0 || headroomBps > 10000) throw new LifecyclePlanningError("INVALID_LIMITS", "Headroom must be between zero and10000 basis points");
49
+ const padding = BigInt(10000 + Math.max(LIFECYCLE_CAPACITY_PADDING_BPS, headroomBps));
50
+ const fits = (gas: bigint) => ((gas + calldataGas) * padding + 9999n) / 10000n <= computeCap;
22
51
  const batches = prepared > 0 ? [prepared] : [];
23
52
  let count = 0, gas = 0n;
24
53
  for (let index = prepared; index < plan.markets.length; index += 1) {
25
54
  const estimate = preparationGasEstimate(plan, index, 1);
26
- if (count > 0 && gas + estimate > computeCap) { batches.push(count); count = 0; gas = 0n; }
55
+ if (!fits(estimate)) throw new LifecyclePlanningError("PREPARATION_GAS_LIMIT", "A market exceeds the preparation gas budget. Reduce its positions before launching.");
56
+ if (count > 0 && !fits(gas + estimate)) { batches.push(count); count = 0; gas = 0n; }
27
57
  count += 1;
28
58
  gas += estimate;
29
59
  }
@@ -53,7 +83,7 @@ export function buildLifecycleCommand(plan: LaunchPlanV1, command: LifecycleComm
53
83
 
54
84
  /** Pure unsigned launch commands. Every command carries the complete commitment;
55
85
  * preparation splits only empty markets, never positions, buys or public opening.
56
- * Allowance discovery, recovery and execution proof belong to the planner. */
86
+ * Allowance discovery, recovery and gas-budget checks belong to the planner. */
57
87
  export function buildLifecycleCommands({ plan, mode, preparationBatches }: BuildLaunchTransactionsOptions, ufg?: LifecycleUfgRoute): LifecycleTransaction[] {
58
88
  if (mode !== "atomic" && mode !== "staged") throw new LifecyclePlanningError("EXPLICIT_MODE_REQUIRED", "Choose atomic or staged explicitly; staged is never silently substituted");
59
89
  if (plan.chainId <= 0n || plan.chainId > BigInt(Number.MAX_SAFE_INTEGER)) throw new LifecyclePlanningError("CHAIN_MISMATCH", "Chain ID must be a positive exact JavaScript integer");
@@ -5,13 +5,10 @@ import type {
5
5
  MarketLiveStateV1, PreparedMarketV1, ProfileRegistrationV1, ProfileTopologyV1, LaunchEnvelopeV2, LifecycleDeveloperTerms,
6
6
  } from "./schema.js";
7
7
 
8
- /** Local opt-in timing only: never contains request arguments, addresses, results or errors.
9
- * Since 0.14.0, removed replay/envelope stages are represented by simulation.measure,
10
- * which includes the final validated execution at the returned gas envelope. */
8
+ /** Local opt-in timing only: never contains request arguments, addresses, results or errors. */
11
9
  export type LifecycleDiagnosticStage =
12
10
  | "plan" | "plan.context" | "plan.domain" | "plan.progress" | "plan.inputs" | "rpc"
13
- | "profile.certification" | "simulation.context" | "simulation.nitro"
14
- | "simulation.poster" | "simulation.measure" | "session-cache";
11
+ | "profile.certification" | "session-cache";
15
12
  export type LifecycleDiagnosticEvent = {
16
13
  stage: LifecycleDiagnosticStage;
17
14
  phase: "queued" | "start" | "success" | "failure" | "reuse";
@@ -31,13 +28,13 @@ export type LifecycleRpcClient = {
31
28
  request(args: { method: string; params?: readonly unknown[] }): Promise<unknown>;
32
29
  /** Opt in to bounded parallel reads only when the supplied transport batches concurrent requests. */
33
30
  supportsReadBatching?: boolean;
34
- /** Optional local observer. Listener failures cannot change execution or admission. */
31
+ /** Optional local observer. Listener failures cannot change planning or sending. */
35
32
  onDiagnostic?: LifecycleDiagnosticListener;
36
33
  /** Caller-owned, opt-in static observations; create with createLifecycleSessionCache(). */
37
34
  sessionCache?: LifecycleSessionCache;
38
35
  };
39
36
  export type LifecycleBlock = { number: bigint; hash: Hash; timestamp: bigint; gasLimit: bigint; baseFeePerGas?: bigint };
40
- /** A session retains pinned static reads and deployment/backend capability observations. */
37
+ /** A session retains pinned static reads and deployment metadata observations. */
41
38
  export type LifecycleSessionCache = {
42
39
  readonly block: Readonly<Pick<LifecycleBlock, "number" | "hash">> | undefined;
43
40
  /** Call on wallet/chain changes and after every confirmed transaction. */
@@ -48,8 +45,6 @@ export type LifecycleLimits = {
48
45
  /** Optional tightening caps on the complete transaction gas envelope, including Nitro poster gas. */
49
46
  headroomBps?: number; chainGasLimit?: bigint; rpcGasLimit?: bigint; accountGasLimit?: bigint;
50
47
  maxCalldataBytes?: number;
51
- /** Optional aggregate gas-used policy ceiling for one simulation request; no SDK-invented default window. */
52
- maxSimulationGas?: bigint;
53
48
  chainId?: bigint; orchestrator?: Address; account?: Address; observedBlockNumber?: bigint; observedBlockHash?: Hash;
54
49
  /** External data fee not already charged in gas, called with exact calldata and the pinned block.
55
50
  * Nitro poster fees are already included in gas, bounded locally from same-review ArbGasInfo prices. */
@@ -59,18 +54,10 @@ export type LifecycleLimitSource = LifecycleLimits | ((context: LifecycleLimitCo
59
54
  export type ResolvedLifecycleLimits = {
60
55
  /** Fixed native transaction ceiling, including poster gas; caller caps may refuse but never resize it. */
61
56
  executionGasCeiling: bigint; transactionGasCeiling?: bigint; protocol: "evm" | "nitro";
62
- arbOSVersion?: bigint;
63
- headroomBps: number; maxCalldataBytes?: number; maxSimulationGas?: bigint;
57
+ headroomBps: number; maxCalldataBytes?: number;
64
58
  blockGasLimit: bigint; chainGasLimit?: bigint; rpcGasLimit?: bigint; accountGasLimit?: bigint;
65
59
  unknownExecutionConstraints: readonly string[]; unknownConstraints: readonly string[];
66
60
  };
67
- /** Only explicitly disposable RPCs may execute snapshot-isolated simulation transactions. */
68
- export type ControlledLifecycleFork = {
69
- client: LifecycleRpcClient; isolation: "disposable"; allowTransactions: true;
70
- expectedChainId?: bigint; expectedBlockHash?: Hash; impersonation?: "anvil" | "hardhat" | "none";
71
- receiptTimeoutMs?: number;
72
- sourceRpcUrl: string; forkRpcUrl: string; resetMethod?: "anvil_reset" | "hardhat_reset";
73
- };
74
61
  export type LifecycleTransactionKind = "approve-reset" | "approve" | "atomic" | "begin" | "prepare" | "activate" | "cancel";
75
62
  export type LifecyclePostcondition =
76
63
  | { kind: "allowance"; asset: Address; spender: Address; minimum: bigint; exact?: bigint }
@@ -81,70 +68,42 @@ export type LifecycleTransaction = {
81
68
  marketStart?: number; marketCount?: number; gas?: bigint; gasPrice?: bigint;
82
69
  /** Exact encoded byte count; populated on SDK-built commands, including approvals. */
83
70
  calldataBytes?: number;
84
- /** Only the immediate command receives its current fee and admission.
85
- * Executable launch gas is the native ceiling; approvals leave gas to the wallet. */
86
- admission?: LifecycleAdmission;
71
+ /** Only the immediate command receives current planning checks and fees.
72
+ * Launch gas is the native ceiling; approvals leave gas to the wallet. */
73
+ assessment?: LifecyclePlanningAssessment;
87
74
  estimate?: LifecycleTransactionEstimate;
88
75
  };
89
76
  export type LifecycleTransactionEstimate = {
90
- /** Present only for measured execution; a ceiling budget never fabricates gas usage. */
91
- gasUsed?: bigint; gasLimit: bigint; gasPrice: bigint; executionFee: bigint; dataFee?: bigint; totalFee?: bigint;
92
- /** Estimated poster allocation within gasLimit, never an exact compute measurement or an extra fee. */
77
+ gasLimit: bigint; gasPrice: bigint; executionFee: bigint; dataFee?: bigint; totalFee?: bigint;
78
+ /** Estimated poster allocation within gasLimit, never a measured or additional fee. */
93
79
  posterGas?: bigint; posterFee?: bigint; dataFeeIncludedInGas: boolean;
94
- feeConfidence: "execution-and-data" | "execution-only" | "native-ceiling-and-data";
95
- };
96
- /** Proof scopes are independent: current execution is not guaranteed wallet submission. */
97
- export type LifecycleProofOutcomes = {
98
- executionProof: "proved" | "failed" | "unavailable" | "not-run";
99
- protocolFit: "proved" | "failed" | "unknown" | "profiled";
100
- };
101
- export type LifecycleAdmission = LifecycleProofOutcomes & {
102
- admitted: boolean; confidence: "stateful" | "provisional" | "profiled";
103
- blockNumber: bigint; blockHash: Hash; account: Address; chainId: bigint;
104
- reason?: string; limits: ResolvedLifecycleLimits;
105
- };
106
- export type LifecycleFailureCategory = "semantic" | "capacity" | "opaque" | "source" | "postcondition" | "affordability";
107
- export type LifecycleCapacityConstraint = "compute" | "gas-envelope" | "calldata" | "simulation-gas" | "activation";
108
- export type LifecycleSimulationStep = {
109
- transactionId: string; success: boolean; gasUsed?: bigint; gasLimit?: bigint; gasRequired?: bigint;
110
- returnData?: Hex; error?: string; estimate?: LifecycleTransactionEstimate;
111
- /** Suffix proof is historical and provisional; only a fresh build admits
112
- * its immediate transaction, still at the native ceiling and current fee. */
113
- provisional?: boolean;
114
- failureCategory?: LifecycleFailureCategory; decodedError?: string;
115
- /** Safe failed-call facts only; native messages and error-data bytes are never copied here. */
116
- nativeErrorCode?: number;
117
- nativeErrorKind?: "out-of-gas" | "execution-reverted" | "vm-error" | "other" | "missing";
118
- nativeErrorDataBytes?: number;
119
- /** Explicit native simulator report, not inferred from gas consumption or the requested limit. */
120
- nativeGasCapped?: boolean;
80
+ feeConfidence: "native-ceiling-and-data" | "native-ceiling-only";
121
81
  };
82
+ export type LifecycleFailureCategory = "semantic" | "capacity" | "affordability";
83
+ export type LifecycleCapacityConstraint = "gas-envelope" | "calldata" | "activation" | "preparation";
122
84
  export type LifecycleOpeningBuyQuote = {
123
85
  buyIndex: number; marketIndex: number; quoteAmountIn: bigint; quoteSpent: bigint;
124
86
  tokenOut: bigint; sqrtPriceAfterX96: bigint;
125
87
  };
126
- /** Conservative compute bounds used for mode/capacity decisions, never gas-limit sizing.
127
- * An upper bound above the ceiling is uncertain, not proof of impossibility. */
88
+ /** Versioned compute budgets with headroom, never transaction gas-limit sizing.
89
+ * Atomic budget is absent when conversion work is outside the template model. */
128
90
  export type LifecycleLaunchGasBounds = {
129
- atomicComputeGasUpperBound: bigint; activationComputeGasUpperBound: bigint;
91
+ atomicComputeGasUpperBound?: bigint; activationComputeGasUpperBound: bigint;
130
92
  };
131
- export type LifecycleGasProfileEvidence = {
93
+ export type LifecycleGasProfile = {
132
94
  version: string; bounds: LifecycleLaunchGasBounds;
133
95
  initialBuys: readonly LifecycleOpeningBuyQuote[];
134
96
  };
135
- export type LifecycleSimulation = LifecycleProofOutcomes & {
136
- backend: "eth_simulateV1" | "controlled-fork" | "unavailable" | "profiled";
137
- /** Stateful execution or versioned profile coverage; only the immediate envelope is final. */
138
- confidence: "stateful" | "provisional" | "profiled"; admitted: boolean;
97
+ /** Pinned input and gas-budget checks only. No transaction is simulated or proved. */
98
+ export type LifecyclePlanningAssessment = {
99
+ ready: boolean;
139
100
  blockNumber: bigint; blockHash: Hash; account: Address; chainId: bigint;
140
- steps: readonly LifecycleSimulationStep[]; limits: ResolvedLifecycleLimits;
141
- /** Immediate fixed-ceiling fee budget; absent for wallet-prepared approvals. */
101
+ limits: ResolvedLifecycleLimits;
102
+ /** Immediate native-ceiling fee budget; absent for wallet-prepared approvals. */
142
103
  estimate?: LifecycleTransactionEstimate;
143
- gasProfile?: LifecycleGasProfileEvidence;
144
- /** Work outside the returned admission, including an RPC-cap failed suffix. */
145
- deferredTransactionIds: readonly string[];
146
- reason?: string; failedTransactionId?: string;
147
- /** A payer must reserve the native ceiling up front even if actual gas usage is lower. */
104
+ gasProfile?: LifecycleGasProfile;
105
+ /** Controlled SDK code and user-safe actionable reason, never raw provider errors. */
106
+ code?: string; reason?: string; failedTransactionId?: string;
148
107
  failureCategory?: LifecycleFailureCategory; capacityConstraint?: LifecycleCapacityConstraint;
149
108
  };
150
109
  export type LifecycleFundingPrerequisite = {
@@ -190,24 +149,24 @@ export type PlannedLaunch = {
190
149
  account: Address; chainId: bigint; mode: LaunchExecutionMode; confirmations: number;
191
150
  /** Opt-in proxy routing; the committed creator remains the proxy, account is its principal. */
192
151
  ufg?: { config: UfgLaunchConfig; configHash: Hash };
193
- /** Only transactions[0] has fresh immediate admission/fees. Launch gas is fixed
194
- * at the native ceiling; wallet-assigned nonce and approval gas are omitted. */
152
+ /** Only transactions[0] has fresh immediate planning checks/fees. Launch gas is
153
+ * the native ceiling; wallet-assigned nonce and approval gas are omitted. */
195
154
  transactions: readonly LifecycleTransaction[]; prerequisites: readonly LifecycleFundingPrerequisite[];
196
155
  /** Sum of exact calldata bytes across the returned remaining commands, including approvals. */
197
156
  totalCalldataBytes: number;
198
- profiles: readonly (LifecycleProfile | LifecycleConstructionProfile)[]; simulation: LifecycleSimulation;
157
+ profiles: readonly (LifecycleProfile | LifecycleConstructionProfile)[]; assessment: LifecyclePlanningAssessment;
199
158
  /** Exact CREATE2 metadata captured from the final committed bound markets. */
200
159
  hookDeployments: readonly LifecyclePoolBoundHookDeployment[];
201
160
  progress: CanonicalLaunchProgress;
202
161
  limits?: LifecycleLimitSource;
203
- /** Unstarted-launch admission choices only; never part of the committed plan or calldata. */
162
+ /** Unstarted-launch construction choices; never part of committed calldata. */
204
163
  allowTopologyGaps?: boolean; allowMissingPermanentTail?: boolean;
205
164
  };
206
165
  export type PlanLaunchOptions = {
207
166
  client: LifecycleRpcClient; account: Address; plan: LaunchPlanV1;
208
- /** Atomic is a preference: conservative capacity may select staged before begin.
209
- * Explicit staged and an already-started launch's recorded mode are retained. */
210
- mode: LaunchExecutionMode; limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork; receipts?: readonly LifecycleReceiptReference[];
167
+ /** Atomic requires one market, no conversion and a known budget fitting with headroom.
168
+ * All other unstarted launches are staged; started launches retain canonical mode. */
169
+ mode: LaunchExecutionMode; limits?: LifecycleLimitSource; receipts?: readonly LifecycleReceiptReference[];
211
170
  confirmations?: number; signal?: AbortSignal;
212
171
  /** Opt in to the pinned UFG proxy; sender must match the nonce's principal namespace. */
213
172
  ufg?: { config: UfgLaunchConfig };
@@ -218,8 +177,8 @@ export type PlanLaunchOptions = {
218
177
  };
219
178
  export type PrepareAndPlanLifecycleLaunchOptions = PlanLaunchOptions & {
220
179
  onProgress?: (progress: PoolBoundLifecyclePreparationProgress) => void;
221
- /** Protect ordered buys from exact local curve outputs or native diagnostics,
222
- * rounded down. Omitted preserves committed minima; unstarted launches only. */
180
+ /** Protect ordered buys from exact local curve outputs, rounded down.
181
+ * Omitted preserves committed minima; unstarted launches only. */
223
182
  buySlippageBps?: number;
224
183
  };
225
184
  export type BuildLaunchTransactionsOptions = {
@@ -227,29 +186,21 @@ export type BuildLaunchTransactionsOptions = {
227
186
  /** Positive ordered preparation counts covering every market exactly. Staged only. */
228
187
  preparationBatches?: readonly number[];
229
188
  };
230
- export type SimulateLaunchPlanOptions = {
231
- client: LifecycleRpcClient; planned: PlannedLaunch; limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork;
232
- /** Submitted receipt evidence and confirmation depth are inherited from the
233
- * stored plan when omitted, exactly as build-next consumes them; resimulation
234
- * never silently drops submitted-transaction context. */
235
- receipts?: readonly LifecycleReceiptReference[]; confirmations?: number;
236
- signal?: AbortSignal;
237
- };
238
189
  export type ReadLaunchProgressOptions = {
239
190
  client: LifecycleRpcClient; planned: Pick<PlannedLaunch, "plan" | "planHash" | "launchId" | "predictedToken" | "account" | "mode" | "confirmations" | "ufg">;
240
191
  receipts?: readonly LifecycleReceiptReference[]; confirmations?: number;
241
192
  signal?: AbortSignal;
242
193
  };
243
194
  export type BuildNextTransactionOptions = ReadLaunchProgressOptions & {
244
- planned: PlannedLaunch; action?: "continue" | "cancel"; limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork;
195
+ planned: PlannedLaunch; action?: "continue" | "cancel"; limits?: LifecycleLimitSource;
245
196
  /** Untrusted reviewed intent/fee. Gas differing from the native ceiling is stale;
246
197
  * never resize it, bump a held fee or assign a wallet nonce. */
247
198
  reviewedTransaction?: LifecycleTransaction;
248
199
  };
249
200
  export class LifecyclePlanningError extends Error {
250
201
  readonly code: string;
251
- readonly simulation?: LifecycleSimulation;
252
- constructor(code: string, message: string, simulation?: LifecycleSimulation) {
253
- super(message); this.name = "LifecyclePlanningError"; this.code = code; this.simulation = simulation;
202
+ readonly assessment?: LifecyclePlanningAssessment;
203
+ constructor(code: string, message: string, assessment?: LifecyclePlanningAssessment) {
204
+ super(message); this.name = "LifecyclePlanningError"; this.code = code; this.assessment = assessment;
254
205
  }
255
206
  }
@@ -10,7 +10,7 @@ import { buildUfgFeeAssetPolicies, encodeUfgLaunchConfig, hashUfgLaunchConfig, i
10
10
 
11
11
  export { UFG_LAUNCH_PROXY_ADDRESS, UFG_TREASURY_FACTORY_ADDRESS, UFG_UPSTREAM_FACTORY_ADDRESS, UFG_ORCHESTRATOR_ADDRESS, UFG_FIXED_PROFILE_ID, UFG_DYNAMIC_PROFILE_ID, UFG_FIXED_ADAPTER_ID, UFG_DYNAMIC_ADAPTER_ID, isUfgProfile, ufgLaunchConfigComponents, encodeUfgLaunchConfig, decodeUfgLaunchConfig, hashUfgLaunchConfig, validateUfgLaunchConfig, ufgLaunchNonce, buildUfgFeeAssetPolicies, type UfgLaunchConfig } from "./ufg-config.js";
12
12
 
13
- /** Offline proxy-specific admission. Live token/reserve code, registry and transfer checks still require simulation. */
13
+ /** Offline proxy-specific intent checks. Registry, transfers and reserve behavior are enforced on-chain. */
14
14
  export function validateUfgLaunchPlan(plan: LaunchPlanV1, config: UfgLaunchConfig, predictedToken: Address): void {
15
15
  try {
16
16
  ufgPlanPrincipal(plan);
@@ -1,15 +0,0 @@
1
- import { type ControlledLifecycleFork } from "./types.js";
2
- /**
3
- * Connects an explicitly disposable loopback fork. Only the fork receives resets/transactions;
4
- * sourceRpcUrl is used by the fork node for read-only canonical state synchronization.
5
- */
6
- export declare function createControlledLifecycleFork(options: {
7
- sourceRpcUrl: string;
8
- forkRpcUrl: string;
9
- allowTransactions: true;
10
- fetch?: typeof globalThis.fetch;
11
- impersonation?: "anvil" | "hardhat" | "none";
12
- resetMethod?: "anvil_reset" | "hardhat_reset";
13
- receiptTimeoutMs?: number;
14
- }): ControlledLifecycleFork;
15
- //# sourceMappingURL=fork.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fork.d.ts","sourceRoot":"","sources":["../../src/lifecycle/fork.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,uBAAuB,EAA2B,MAAM,YAAY,CAAC;AAG3G;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,IAAI,CAAC;IAClE,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC9E,WAAW,CAAC,EAAE,aAAa,GAAG,eAAe,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1E,GAAG,uBAAuB,CAwB1B"}
@@ -1,36 +0,0 @@
1
- import { LifecyclePlanningError } from "./types.js";
2
- import { rpcObject } from "./rpc.js";
3
- /**
4
- * Connects an explicitly disposable loopback fork. Only the fork receives resets/transactions;
5
- * sourceRpcUrl is used by the fork node for read-only canonical state synchronization.
6
- */
7
- export function createControlledLifecycleFork(options) {
8
- const source = new URL(options.sourceRpcUrl);
9
- const fork = new URL(options.forkRpcUrl);
10
- if (!["http:", "https:"].includes(source.protocol) || !["http:", "https:"].includes(fork.protocol))
11
- throw new LifecyclePlanningError("UNSAFE_FORK", "Controlled fork RPCs must use HTTP(S)");
12
- const loopback = ["localhost", "127.0.0.1", "[::1]", "::1"];
13
- const sourcePort = source.port || (source.protocol === "https:" ? "443" : "80");
14
- const forkPort = fork.port || (fork.protocol === "https:" ? "443" : "80");
15
- if (!loopback.includes(fork.hostname) || (loopback.includes(source.hostname) && sourcePort === forkPort) || source.href === fork.href || options.allowTransactions !== true)
16
- throw new LifecyclePlanningError("UNSAFE_FORK", "Controlled fork must be an explicit, distinct disposable loopback RPC, not a localhost/IP alias of the source");
17
- const fetch = options.fetch ?? globalThis.fetch;
18
- let id = 0;
19
- const client = {
20
- async request({ method, params }) {
21
- const response = await fetch(fork.href, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: ++id, method, params: params ?? [] }) });
22
- if (!response.ok)
23
- throw new LifecyclePlanningError("FORK_RPC_ERROR", `Disposable fork RPC returned HTTP ${response.status}`);
24
- const result = rpcObject(await response.json(), "fork JSON-RPC envelope");
25
- if (result.error !== undefined) {
26
- const error = rpcObject(result.error, "fork JSON-RPC error");
27
- throw new LifecyclePlanningError("FORK_RPC_ERROR", typeof error.message === "string" ? error.message : "Disposable fork RPC returned an error");
28
- }
29
- if (!("result" in result))
30
- throw new LifecyclePlanningError("INVALID_RPC_RESPONSE", "Disposable fork RPC omitted its result");
31
- return result.result;
32
- },
33
- };
34
- return { client, isolation: "disposable", allowTransactions: true, sourceRpcUrl: source.href, forkRpcUrl: fork.href, resetMethod: options.resetMethod ?? "anvil_reset", impersonation: options.impersonation ?? "anvil", receiptTimeoutMs: options.receiptTimeoutMs };
35
- }
36
- //# sourceMappingURL=fork.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fork.js","sourceRoot":"","sources":["../../src/lifecycle/fork.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import { type LifecycleBlock, type LifecycleSimulation, type LifecycleTransaction, type SimulateLaunchPlanOptions } from "./types.js";
2
- /** Internal, operation-local fee envelope for the already matched immediate step. */
3
- export type NextTransactionEnvelope = Readonly<{
4
- gas: bigint;
5
- gasPrice: bigint;
6
- }>;
7
- export type PreparedLaunchSimulation = ((transactions: readonly LifecycleTransaction[], nextEnvelope?: NextTransactionEnvelope) => Promise<LifecycleSimulation>) & {
8
- /** Unadmitted diagnostic results only; final measurement validates exact calldata. */
9
- measure(transactions: readonly LifecycleTransaction[]): Promise<LifecycleSimulation>;
10
- close(): void;
11
- };
12
- export declare function observedFields<T extends object>(value: T): () => boolean;
13
- /** Internal continuation owned by one SDK read invocation. Only its positive
14
- * capability proof is reused; every candidate executes its entire economic sequence. */
15
- export declare function prepareLaunchSimulation(options: SimulateLaunchPlanOptions, block: LifecycleBlock, hasTransactions?: boolean, immediate?: boolean): PreparedLaunchSimulation;
16
- export declare function simulateLaunchTransactions(options: SimulateLaunchPlanOptions, transactions: readonly LifecycleTransaction[], pinnedBlock?: LifecycleBlock, nextEnvelope?: NextTransactionEnvelope): Promise<LifecycleSimulation>;
17
- //# sourceMappingURL=simulation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"simulation.d.ts","sourceRoot":"","sources":["../../src/lifecycle/simulation.ts"],"names":[],"mappings":"AAIA,OAAO,EAAwD,KAAK,cAAc,EAAoF,KAAK,mBAAmB,EAAgC,KAAK,oBAAoB,EAAoD,KAAK,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAoS9V,qFAAqF;AACrF,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAClF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,EAAE,YAAY,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG;IACjK,sFAAsF;IACtF,OAAO,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrF,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,OAAO,CAIxE;AAED;wFACwF;AACxF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,cAAc,EAAE,eAAe,UAAO,EAAE,SAAS,UAAQ,GAAG,wBAAwB,CAgHtK;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,SAAS,oBAAoB,EAAE,EAAE,WAAW,CAAC,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAStO"}