@black-market/sdk 0.6.4 → 0.7.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.
- package/README.md +28 -4
- package/dist/addresses.d.ts +1 -1
- package/dist/addresses.js +4 -4
- package/dist/launch.d.ts +61 -0
- package/dist/launch.d.ts.map +1 -1
- package/dist/launch.js +171 -6
- package/dist/launch.js.map +1 -1
- package/dist/lifecycle/abi.d.ts +1999 -253
- package/dist/lifecycle/abi.d.ts.map +1 -1
- package/dist/lifecycle/abi.js +43 -14
- package/dist/lifecycle/abi.js.map +1 -1
- package/dist/lifecycle/allocations.d.ts +11 -0
- package/dist/lifecycle/allocations.d.ts.map +1 -0
- package/dist/lifecycle/allocations.js +36 -0
- package/dist/lifecycle/allocations.js.map +1 -0
- package/dist/lifecycle/calibration.d.ts +19 -0
- package/dist/lifecycle/calibration.d.ts.map +1 -0
- package/dist/lifecycle/calibration.js +65 -0
- package/dist/lifecycle/calibration.js.map +1 -0
- package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.d.ts +11 -0
- package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.d.ts.map +1 -0
- package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.js +10 -0
- package/dist/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.js.map +1 -0
- package/dist/lifecycle/index.d.ts +4 -2
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -2
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/lifecycle/markets.d.ts +170 -6
- package/dist/lifecycle/markets.d.ts.map +1 -1
- package/dist/lifecycle/markets.js +164 -37
- package/dist/lifecycle/markets.js.map +1 -1
- package/dist/lifecycle/planner.d.ts +7 -14
- package/dist/lifecycle/planner.d.ts.map +1 -1
- package/dist/lifecycle/planner.js +354 -400
- package/dist/lifecycle/planner.js.map +1 -1
- package/dist/lifecycle/presets.d.ts +62 -0
- package/dist/lifecycle/presets.d.ts.map +1 -0
- package/dist/lifecycle/presets.js +195 -0
- package/dist/lifecycle/presets.js.map +1 -0
- package/dist/lifecycle/progress.d.ts +5 -1
- package/dist/lifecycle/progress.d.ts.map +1 -1
- package/dist/lifecycle/progress.js +212 -53
- package/dist/lifecycle/progress.js.map +1 -1
- package/dist/lifecycle/rpc.d.ts +13 -2
- package/dist/lifecycle/rpc.d.ts.map +1 -1
- package/dist/lifecycle/rpc.js +92 -8
- package/dist/lifecycle/rpc.js.map +1 -1
- package/dist/lifecycle/simulation.d.ts +14 -4
- package/dist/lifecycle/simulation.d.ts.map +1 -1
- package/dist/lifecycle/simulation.js +381 -118
- package/dist/lifecycle/simulation.js.map +1 -1
- package/dist/lifecycle/transactions.d.ts +6 -0
- package/dist/lifecycle/transactions.d.ts.map +1 -0
- package/dist/lifecycle/transactions.js +40 -0
- package/dist/lifecycle/transactions.js.map +1 -0
- package/dist/lifecycle/types.d.ts +39 -2
- package/dist/lifecycle/types.d.ts.map +1 -1
- package/dist/lifecycle/types.js.map +1 -1
- package/docs/launch-lifecycle.md +228 -54
- package/examples/README.md +108 -18
- package/examples/generate-lifecycle-commitment-fixture.mjs +3 -1
- package/examples/launch-example-support.mjs +1 -1
- package/examples/launch-example.mjs +73 -26
- package/examples/launch-lifecycle-smoke.mjs +13 -11
- package/examples/launch.mjs +12 -11
- package/examples/quickstart.mjs +1 -1
- package/package.json +1 -1
- package/src/addresses.ts +4 -4
- package/src/launch.ts +213 -6
- package/src/lifecycle/abi.ts +43 -14
- package/src/lifecycle/allocations.ts +35 -0
- package/src/lifecycle/calibration.ts +59 -0
- package/src/lifecycle/deployments/fixed-fee-pool-hook-v1-20261008.ts +11 -0
- package/src/lifecycle/index.ts +4 -2
- package/src/lifecycle/markets.ts +169 -35
- package/src/lifecycle/planner.ts +326 -330
- package/src/lifecycle/presets.ts +243 -0
- package/src/lifecycle/progress.ts +193 -50
- package/src/lifecycle/rpc.ts +97 -9
- package/src/lifecycle/simulation.ts +369 -111
- package/src/lifecycle/transactions.ts +34 -0
- 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
|
+
}
|
package/src/lifecycle/types.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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;
|