@black-market/sdk 0.6.3 → 0.7.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 (82) hide show
  1. package/README.md +28 -4
  2. package/dist/addresses.d.ts +1 -1
  3. package/dist/addresses.js +4 -4
  4. package/dist/launch.d.ts +61 -0
  5. package/dist/launch.d.ts.map +1 -1
  6. package/dist/launch.js +171 -6
  7. package/dist/launch.js.map +1 -1
  8. package/dist/lifecycle/abi.d.ts +1999 -253
  9. package/dist/lifecycle/abi.d.ts.map +1 -1
  10. package/dist/lifecycle/abi.js +43 -14
  11. package/dist/lifecycle/abi.js.map +1 -1
  12. package/dist/lifecycle/allocations.d.ts +11 -0
  13. package/dist/lifecycle/allocations.d.ts.map +1 -0
  14. package/dist/lifecycle/allocations.js +36 -0
  15. package/dist/lifecycle/allocations.js.map +1 -0
  16. package/dist/lifecycle/calibration.d.ts +19 -0
  17. package/dist/lifecycle/calibration.d.ts.map +1 -0
  18. package/dist/lifecycle/calibration.js +65 -0
  19. package/dist/lifecycle/calibration.js.map +1 -0
  20. package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.d.ts +11 -0
  21. package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.d.ts.map +1 -0
  22. package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.js +10 -0
  23. package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.js.map +1 -0
  24. package/dist/lifecycle/index.d.ts +4 -2
  25. package/dist/lifecycle/index.d.ts.map +1 -1
  26. package/dist/lifecycle/index.js +4 -2
  27. package/dist/lifecycle/index.js.map +1 -1
  28. package/dist/lifecycle/markets.d.ts +170 -6
  29. package/dist/lifecycle/markets.d.ts.map +1 -1
  30. package/dist/lifecycle/markets.js +164 -37
  31. package/dist/lifecycle/markets.js.map +1 -1
  32. package/dist/lifecycle/planner.d.ts +7 -14
  33. package/dist/lifecycle/planner.d.ts.map +1 -1
  34. package/dist/lifecycle/planner.js +355 -392
  35. package/dist/lifecycle/planner.js.map +1 -1
  36. package/dist/lifecycle/presets.d.ts +62 -0
  37. package/dist/lifecycle/presets.d.ts.map +1 -0
  38. package/dist/lifecycle/presets.js +195 -0
  39. package/dist/lifecycle/presets.js.map +1 -0
  40. package/dist/lifecycle/progress.d.ts +5 -1
  41. package/dist/lifecycle/progress.d.ts.map +1 -1
  42. package/dist/lifecycle/progress.js +286 -118
  43. package/dist/lifecycle/progress.js.map +1 -1
  44. package/dist/lifecycle/rpc.d.ts +13 -2
  45. package/dist/lifecycle/rpc.d.ts.map +1 -1
  46. package/dist/lifecycle/rpc.js +92 -8
  47. package/dist/lifecycle/rpc.js.map +1 -1
  48. package/dist/lifecycle/simulation.d.ts +14 -1
  49. package/dist/lifecycle/simulation.d.ts.map +1 -1
  50. package/dist/lifecycle/simulation.js +400 -100
  51. package/dist/lifecycle/simulation.js.map +1 -1
  52. package/dist/lifecycle/transactions.d.ts +6 -0
  53. package/dist/lifecycle/transactions.d.ts.map +1 -0
  54. package/dist/lifecycle/transactions.js +40 -0
  55. package/dist/lifecycle/transactions.js.map +1 -0
  56. package/dist/lifecycle/types.d.ts +39 -2
  57. package/dist/lifecycle/types.d.ts.map +1 -1
  58. package/dist/lifecycle/types.js.map +1 -1
  59. package/docs/launch-lifecycle.md +236 -39
  60. package/examples/README.md +108 -18
  61. package/examples/generate-lifecycle-commitment-fixture.mjs +3 -1
  62. package/examples/launch-example-support.mjs +1 -1
  63. package/examples/launch-example.mjs +73 -26
  64. package/examples/launch-lifecycle-smoke.mjs +13 -11
  65. package/examples/launch.mjs +12 -11
  66. package/examples/quickstart.mjs +1 -1
  67. package/package.json +1 -1
  68. package/src/addresses.ts +4 -4
  69. package/src/launch.ts +213 -6
  70. package/src/lifecycle/abi.ts +43 -14
  71. package/src/lifecycle/allocations.ts +35 -0
  72. package/src/lifecycle/calibration.ts +59 -0
  73. package/src/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.ts +11 -0
  74. package/src/lifecycle/index.ts +4 -2
  75. package/src/lifecycle/markets.ts +169 -35
  76. package/src/lifecycle/planner.ts +326 -321
  77. package/src/lifecycle/presets.ts +243 -0
  78. package/src/lifecycle/progress.ts +254 -102
  79. package/src/lifecycle/rpc.ts +97 -9
  80. package/src/lifecycle/simulation.ts +391 -94
  81. package/src/lifecycle/transactions.ts +34 -0
  82. package/src/lifecycle/types.ts +35 -3
@@ -0,0 +1,34 @@
1
+ import { encodeFunctionData } from "viem";
2
+ import { launchLifecycleAbi } from "./abi.js";
3
+ import { LifecycleFundingKind, LifecycleMode } from "./schema.js";
4
+ import { LifecyclePlanningError, type BuildLaunchTransactionsOptions, type LifecycleTransaction } from "./types.js";
5
+ import { assertLifecycleTokenAllocation } from "./allocations.js";
6
+
7
+ /** Pure unsigned launch commands. Every command carries the complete commitment;
8
+ * preparation splits only empty markets, never positions, buys or public opening.
9
+ * Allowance discovery, recovery and execution proof belong to the planner. */
10
+ export function buildLaunchTransactions({ plan, mode, preparationBatches }: BuildLaunchTransactionsOptions): LifecycleTransaction[] {
11
+ if (mode !== "atomic" && mode !== "staged") throw new LifecyclePlanningError("EXPLICIT_MODE_REQUIRED", "Choose atomic or staged explicitly; staged is never silently substituted");
12
+ 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");
13
+ if (plan.markets.length === 0 || plan.markets.length > 16) throw new LifecyclePlanningError("INVALID_MARKET_COUNT", "A launch requires between one and sixteen markets");
14
+ if (mode === "atomic" && preparationBatches !== undefined) throw new LifecyclePlanningError("INVALID_PREPARATION_BATCHES", "Atomic execution has no separate preparation batches");
15
+ assertLifecycleTokenAllocation(plan);
16
+ const nativeValue = plan.funding.reduce((total, funding) => total + (funding.kind === LifecycleFundingKind.NativeWrap || funding.kind === LifecycleFundingKind.Swap && BigInt(funding.inputAsset) === 0n ? funding.inputAmount : 0n), 0n);
17
+ const base = { chainId: Number(plan.chainId), from: plan.creator, to: plan.orchestrator };
18
+ const transactions: LifecycleTransaction[] = [];
19
+ if (mode === "atomic") {
20
+ transactions.push({ ...base, id: "atomic", kind: "atomic", data: encodeFunctionData({ abi: launchLifecycleAbi, functionName: "launchAtomic", args: [plan] }), value: nativeValue, dependencies: [], postconditions: [{ kind: "launch", phase: "Active", preparedMarkets: plan.markets.length }] });
21
+ } else {
22
+ const batches = preparationBatches ?? [plan.markets.length];
23
+ if (batches.length === 0 || batches.some((count) => !Number.isSafeInteger(count) || count <= 0) || batches.reduce((total, count) => total + count, 0) !== plan.markets.length) throw new LifecyclePlanningError("INVALID_PREPARATION_BATCHES", "Positive ordered preparation counts must cover every market exactly");
24
+ transactions.push({ ...base, id: "begin", kind: "begin", data: encodeFunctionData({ abi: launchLifecycleAbi, functionName: "beginLaunch", args: [plan, LifecycleMode.Staged] }), value: nativeValue, dependencies: [], postconditions: [{ kind: "launch", phase: "Preparing", preparedMarkets: 0 }] });
25
+ let first = 0;
26
+ for (const count of batches) {
27
+ const completed = first + count;
28
+ transactions.push({ ...base, id: `prepare:${first}:${count}`, kind: "prepare", data: encodeFunctionData({ abi: launchLifecycleAbi, functionName: "prepareMarkets", args: [plan, first, count] }), value: 0n, dependencies: [], marketStart: first, marketCount: count, postconditions: [{ kind: "launch", phase: completed === plan.markets.length ? "Ready" : "Preparing", preparedMarkets: completed }] });
29
+ first = completed;
30
+ }
31
+ transactions.push({ ...base, id: "activate", kind: "activate", data: encodeFunctionData({ abi: launchLifecycleAbi, functionName: "activateLaunch", args: [plan] }), value: 0n, dependencies: [], postconditions: [{ kind: "launch", phase: "Active", preparedMarkets: plan.markets.length }] });
32
+ }
33
+ return transactions.map((transaction, index) => ({ ...transaction, calldataBytes: (transaction.data.length - 2) / 2, dependencies: index === 0 ? [] : [transactions[index - 1]!.id] }));
34
+ }
@@ -62,6 +62,8 @@ export type LifecycleTransaction = {
62
62
  id: string; kind: LifecycleTransactionKind; chainId: number; from: Address; to: Address; data: Hex; value: bigint;
63
63
  dependencies: readonly string[]; postconditions: readonly LifecyclePostcondition[];
64
64
  marketStart?: number; marketCount?: number; gas?: bigint; gasPrice?: bigint;
65
+ /** Exact encoded byte count; populated on SDK-built commands, including approvals. */
66
+ calldataBytes?: number;
65
67
  /** Exact current-state execution admission, not a wallet batch or future guarantee. */
66
68
  admission?: LifecycleAdmission;
67
69
  estimate?: LifecycleTransactionEstimate;
@@ -83,9 +85,18 @@ export type LifecycleAdmission = LifecycleProofOutcomes & {
83
85
  blockNumber: bigint; blockHash: Hash; account: Address; chainId: bigint;
84
86
  reason?: string; limits: ResolvedLifecycleLimits;
85
87
  };
88
+ export type LifecycleFailureCategory = "semantic" | "capacity" | "opaque" | "source" | "postcondition" | "affordability";
89
+ export type LifecycleCapacityConstraint = "compute" | "gas-envelope" | "calldata" | "simulation-gas";
86
90
  export type LifecycleSimulationStep = {
87
91
  transactionId: string; success: boolean; gasUsed?: bigint; gasLimit?: bigint; gasRequired?: bigint;
88
92
  returnData?: Hex; error?: string; estimate?: LifecycleTransactionEstimate;
93
+ failureCategory?: LifecycleFailureCategory; decodedError?: string;
94
+ /** Safe failed-call facts only; native messages and error-data bytes are never copied here. */
95
+ nativeErrorCode?: number;
96
+ nativeErrorKind?: "out-of-gas" | "execution-reverted" | "vm-error" | "other" | "missing";
97
+ nativeErrorDataBytes?: number;
98
+ /** Explicit native simulator report, not inferred from gas consumption or the requested limit. */
99
+ nativeGasCapped?: boolean;
89
100
  };
90
101
  export type LifecycleSimulation = LifecycleProofOutcomes & {
91
102
  backend: "eth_simulateV1" | "controlled-fork" | "unavailable";
@@ -93,6 +104,7 @@ export type LifecycleSimulation = LifecycleProofOutcomes & {
93
104
  blockNumber: bigint; blockHash: Hash; account: Address; chainId: bigint;
94
105
  steps: readonly LifecycleSimulationStep[]; limits: ResolvedLifecycleLimits;
95
106
  reason?: string; failedTransactionId?: string;
107
+ failureCategory?: LifecycleFailureCategory; capacityConstraint?: LifecycleCapacityConstraint;
96
108
  };
97
109
  export type LifecycleFundingPrerequisite = {
98
110
  funding: AssetFundingV1; inputBalance: bigint; requiredInput: bigint;
@@ -104,6 +116,8 @@ export type LifecycleProfile = {
104
116
  envelope?: LaunchEnvelopeV2; developerTerms?: LifecycleDeveloperTerms; protocolMaximumDeveloperFeeBps?: number;
105
117
  admitted: boolean; reason?: string;
106
118
  };
119
+ /** Release construction data only. Current registry eligibility is not asserted. */
120
+ export type LifecycleConstructionProfile = Omit<LifecycleProfile, "admitted" | "reason"> & { metadataSource: "preset" };
107
121
  export type LifecycleMarketProgress = {
108
122
  index: number; prepared: PreparedMarketV1; live?: MarketLiveStateV1; error?: string;
109
123
  };
@@ -131,16 +145,29 @@ export type PlannedLaunch = {
131
145
  tokenFactory: Address; tokenFactoryCodeHash: Hex;
132
146
  account: Address; chainId: bigint; mode: LaunchExecutionMode; confirmations: number;
133
147
  transactions: readonly LifecycleTransaction[]; prerequisites: readonly LifecycleFundingPrerequisite[];
134
- profiles: readonly LifecycleProfile[]; simulation: LifecycleSimulation;
148
+ /** Sum of exact calldata bytes across the returned remaining commands, including approvals. */
149
+ totalCalldataBytes: number;
150
+ profiles: readonly (LifecycleProfile | LifecycleConstructionProfile)[]; simulation: LifecycleSimulation;
135
151
  /** Exact CREATE2 metadata captured from the final committed bound markets. */
136
152
  hookDeployments: readonly LifecyclePoolBoundHookDeployment[];
137
- atomicAttempt: LifecycleSimulation; progress: CanonicalLaunchProgress;
153
+ progress: CanonicalLaunchProgress;
138
154
  preparationBatchSize: number; limits?: LifecycleLimitSource;
139
155
  };
140
156
  export type PlanLaunchOptions = {
141
157
  client: LifecycleRpcClient; account: Address; plan: LaunchPlanV1; mode: LaunchExecutionMode;
142
158
  limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork; receipts?: readonly LifecycleReceiptReference[];
143
- confirmations?: number;
159
+ confirmations?: number; signal?: AbortSignal;
160
+ };
161
+ export type PrepareAndPlanLifecycleLaunchOptions = PlanLaunchOptions & {
162
+ onProgress?: (progress: PoolBoundLifecyclePreparationProgress) => void;
163
+ /** Protect every ordered buy from its actual diagnostic receipt output, rounded down.
164
+ * Omitted preserves the caller's committed minima. Only an unstarted launch may be protected. */
165
+ buySlippageBps?: number;
166
+ };
167
+ export type BuildLaunchTransactionsOptions = {
168
+ plan: LaunchPlanV1; mode: LaunchExecutionMode;
169
+ /** Positive ordered preparation counts covering every market exactly. Staged only. */
170
+ preparationBatches?: readonly number[];
144
171
  };
145
172
  export type SimulateLaunchPlanOptions = {
146
173
  client: LifecycleRpcClient; planned: PlannedLaunch; limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork;
@@ -148,15 +175,20 @@ export type SimulateLaunchPlanOptions = {
148
175
  * stored plan when omitted, exactly as build-next consumes them; resimulation
149
176
  * never silently drops submitted-transaction context. */
150
177
  receipts?: readonly LifecycleReceiptReference[]; confirmations?: number;
178
+ signal?: AbortSignal;
151
179
  };
152
180
  export type ReadLaunchProgressOptions = {
153
181
  client: LifecycleRpcClient; planned: Pick<PlannedLaunch, "plan" | "planHash" | "launchId" | "predictedToken" | "account" | "mode" | "confirmations">;
154
182
  receipts?: readonly LifecycleReceiptReference[]; confirmations?: number;
183
+ signal?: AbortSignal;
155
184
  };
156
185
  export type BuildNextTransactionOptions = ReadLaunchProgressOptions & {
157
186
  planned: PlannedLaunch; action?: "continue" | "cancel"; limits?: LifecycleLimitSource; fork?: ControlledLifecycleFork;
158
187
  /** Optional active submission RPC. Only the immediate next exact transaction is estimated, read-only. */
159
188
  submissionClient?: LifecycleRpcClient;
189
+ /** Untrusted reviewed next envelope. Fresh canonical semantics and complete
190
+ * execution/headroom/affordability proof must accept its exact gas and gasPrice. */
191
+ reviewedTransaction?: LifecycleTransaction;
160
192
  };
161
193
  export class LifecyclePlanningError extends Error {
162
194
  readonly code: string;