@black-market/sdk 0.7.1 → 0.8.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 (57) hide show
  1. package/README.md +58 -22
  2. package/dist/launch.d.ts +31 -5
  3. package/dist/launch.d.ts.map +1 -1
  4. package/dist/launch.js +71 -11
  5. package/dist/launch.js.map +1 -1
  6. package/dist/lifecycle/abi.d.ts +18 -0
  7. package/dist/lifecycle/abi.d.ts.map +1 -1
  8. package/dist/lifecycle/abi.js +4 -0
  9. package/dist/lifecycle/abi.js.map +1 -1
  10. package/dist/lifecycle/index.d.ts +2 -0
  11. package/dist/lifecycle/index.d.ts.map +1 -1
  12. package/dist/lifecycle/index.js +2 -0
  13. package/dist/lifecycle/index.js.map +1 -1
  14. package/dist/lifecycle/planner.d.ts +1 -1
  15. package/dist/lifecycle/planner.d.ts.map +1 -1
  16. package/dist/lifecycle/planner.js +58 -10
  17. package/dist/lifecycle/planner.js.map +1 -1
  18. package/dist/lifecycle/progress.js +35 -35
  19. package/dist/lifecycle/progress.js.map +1 -1
  20. package/dist/lifecycle/rpc.d.ts +10 -4
  21. package/dist/lifecycle/rpc.d.ts.map +1 -1
  22. package/dist/lifecycle/rpc.js +137 -16
  23. package/dist/lifecycle/rpc.js.map +1 -1
  24. package/dist/lifecycle/types.d.ts +20 -1
  25. package/dist/lifecycle/types.d.ts.map +1 -1
  26. package/dist/lifecycle/types.js.map +1 -1
  27. package/docs/launch-lifecycle.md +396 -64
  28. package/examples/.env.example +22 -2
  29. package/examples/README.md +315 -87
  30. package/examples/{launch-erc20-abyss.mjs → launch-erc20-abyss.ts} +1 -1
  31. package/examples/{launch-erc20-burn-mixed.mjs → launch-erc20-burn-mixed.ts} +1 -1
  32. package/examples/launch-erc20-depth-v4.ts +7 -0
  33. package/examples/{launch-erc20-dividends-abyss.mjs → launch-erc20-dividends-abyss.ts} +1 -1
  34. package/examples/launch-erc20-dividends-multiquote-mixed.ts +8 -0
  35. package/examples/launch-erc20-multi-quote.ts +8 -0
  36. package/examples/{launch-erc20-staking-v4.mjs → launch-erc20-staking-v4.ts} +1 -1
  37. package/examples/{launch-erc20-v4.mjs → launch-erc20-v4.ts} +1 -1
  38. package/examples/{launch-erc404-abyss.mjs → launch-erc404-abyss.ts} +1 -1
  39. package/examples/{launch-erc404-dividends-mixed.mjs → launch-erc404-dividends-mixed.ts} +1 -1
  40. package/examples/{launch-erc404-v4.mjs → launch-erc404-v4.ts} +1 -1
  41. package/examples/launch-example-kyber.ts +204 -0
  42. package/examples/launch-example-support.ts +876 -0
  43. package/examples/launch-example.ts +1163 -0
  44. package/examples/{launch-lifecycle-smoke.mjs → launch-lifecycle-smoke.ts} +1 -1
  45. package/examples/{launch.mjs → launch.ts} +1 -1
  46. package/package.json +2 -2
  47. package/src/launch.ts +81 -14
  48. package/src/lifecycle/abi.ts +4 -0
  49. package/src/lifecycle/index.ts +2 -0
  50. package/src/lifecycle/planner.ts +61 -12
  51. package/src/lifecycle/progress.ts +35 -35
  52. package/src/lifecycle/rpc.ts +140 -17
  53. package/src/lifecycle/types.ts +19 -1
  54. package/examples/launch-example-support.mjs +0 -393
  55. package/examples/launch-example.mjs +0 -633
  56. /package/examples/{generate-lifecycle-commitment-fixture.mjs → generate-lifecycle-commitment-fixture.ts} +0 -0
  57. /package/examples/{quickstart.mjs → quickstart.ts} +0 -0
@@ -1,19 +1,26 @@
1
1
  # Examples
2
2
 
3
- The launch examples use the installed public `@black-market/sdk` package and viem,
4
- including when copied into a consumer project. The current chain-4663 graph is the
5
- October8 mined pool-bound V4 config6/V2 and canonical Abyss config1 deployment.
3
+ The launch examples use the public `@black-market/sdk` 0.8.0 package and viem.
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.
6
+ The current chain-4663 graph is
7
+ the October8 mined pool-bound V4 config6/V2 and canonical Abyss config1 deployment.
6
8
  Historical October5 config5 evidence is not relabeled as the new graph. Discovery
7
- is read-only; running a fixed launch example with configured wallet/API deliberately
8
- executes real writes.
9
+ is read-only; fixed launch examples default to an unsigned dry run. Only
10
+ `--broadcast` (or deliberate `--resume` continuation) authorizes real writes.
11
+
12
+ Use Node 24+ to run these TypeScript files directly, for example
13
+ `pnpm build && node examples/quickstart.ts`. No extra runtime dependency or
14
+ `--experimental-strip-types` flag is needed. The build emits the SDK used by the
15
+ examples; their relative support imports use explicit `.ts` extensions for Node ESM.
9
16
 
10
17
  | Script | Behavior |
11
18
  | --- | --- |
12
- | `quickstart.mjs` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
13
- | `launch.mjs` | 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. |
14
- | `generate-lifecycle-commitment-fixture.mjs` | Frozen independent historical config4/Abyss ABI bytes/hash/identity vector. Its pre-cutover allocations are not an executable 0.7.0 plan. |
15
- | `launch-lifecycle-smoke.mjs` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
16
- | `launch-erc20-*.mjs`, `launch-erc404-*.mjs` | Eight independent zero-parameter launch cases with actual SDK admission, local signing, chain verification and mandatory API publication/indexing. |
19
+ | `quickstart.ts` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
20
+ | `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. |
21
+ | `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. |
22
+ | `launch-lifecycle-smoke.ts` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
23
+ | `launch-erc20-*.ts`, `launch-erc404-*.ts` | Eleven independent fixed cases: unsigned end-to-end planning by default; `--broadcast` adds guarded local signing, chain verification and mandatory API publication/indexing. |
17
24
 
18
25
  ## Deployed read-only discovery
19
26
 
@@ -35,7 +42,7 @@ Supply full `LaunchPlanV1` JSON using the selected RPC's current deployment:
35
42
 
36
43
  ```sh
37
44
  pnpm build
38
- node examples/launch.mjs \
45
+ node examples/launch.ts \
39
46
  --plan plan.json --rpc https://rpc.mainnet.chain.robinhood.com/ --mode staged --mine
40
47
  ```
41
48
 
@@ -60,7 +67,7 @@ RPC to build-next. See the
60
67
 
61
68
  For a real new graph, create the saved plan using `readLifecycleProfiles` with its
62
69
  explicit chain/core and admitted pool-bound config6 profile. Supply that graph's RPC
63
- to `launch.mjs`; do not substitute the historical known preset. Applications may use
70
+ to `launch.ts`; do not substitute the historical known preset. Applications may use
64
71
  the existing `LAUNCH_ORCHESTRATOR`, `LAUNCH_IMPLEMENTATION_REGISTRY`, and
65
72
  `LAUNCH_FEE_OWNER_REGISTRY` overrides from the same authentic deployment evidence.
66
73
  The SDK certifies actual registry/creation-code/runtime/constructor bindings and
@@ -84,16 +91,47 @@ See [service prerequisites](../docs/launch-lifecycle.md#real-http-api-integratio
84
91
 
85
92
  ## Individual token creation
86
93
 
87
- **Running one of these files signs and broadcasts a real launch and writes to your
88
- configured API. Mainnet execution is irreversible and spends real funds.** Choose
89
- one command per intended launch; there are no flags, parameters or fixture files.
94
+ **Without a mode flag, these files are dry runs: no transactions are signed or
95
+ broadcast, and no metadata/image is uploaded or published. `--broadcast` signs,
96
+ spends real funds and publishes to your configured API. Mainnet execution is
97
+ irreversible.** Choose one case per intended launch.
98
+
99
+ ### Two-step flow: dry run, then broadcast
100
+
101
+ ```sh
102
+ # 1. Discover, build funding and plan; print the complete economic review and save artifacts.
103
+ node examples/launch-erc20-v4.ts
104
+ # 2. After reviewing the output, explicitly execute the same case.
105
+ node examples/launch-erc20-v4.ts --broadcast
106
+ ```
107
+
108
+ The default output starts with **DRY RUN — no transactions signed or broadcast.**
109
+ It performs the same profile discovery, quote/funding builds, image descriptor
110
+ freezing, economics, salt preparation and planner admission as execution, then
111
+ exits `0` on successful planning. It saves `plan.json`, `economic-review.json`,
112
+ `planning.json` and all other planning evidence in a fresh `launch-results/` directory.
113
+ The creator's public address is derived locally (including authenticated keystore
114
+ decryption when selected), but no wallet signer is created. The final output line
115
+ is the exact case command with `--broadcast` appended.
116
+
117
+ **Choosing `--broadcast` is the authorization. It deliberately skips manual
118
+ economic-review admission: there is no interactive hash prompt or hash input.**
119
+ The full review is still printed and saved, including its computed provenance hash.
120
+ The broadcast run plans afresh with current state, fresh random identity and funding
121
+ builds; it does not submit the dry run's saved plan. Planner admission, unchanged
122
+ economic authority, deadlines, image verification and canonical/reorg barriers remain
123
+ mandatory before signing and publication.
124
+ `--resume <recovery-dir>` retains its existing continuation/publication behavior;
125
+ it does not become a dry run and does not need `--broadcast`. Unknown, duplicated
126
+ or combined mode flags fail before configuration or artifact creation with usage text.
90
127
 
91
128
  ### Setup once
92
129
 
93
130
  Use **Node 24+**. In this repository run `pnpm install`. In a consumer project install
94
131
  both public dependencies with `pnpm add @black-market/sdk viem` (or
95
132
  `npm install @black-market/sdk viem`) and copy the selected files with
96
- `launch-example.mjs` and `launch-example-support.mjs` into `examples/`.
133
+ `launch-example.ts`, `launch-example-support.ts`, and `launch-example-kyber.ts`
134
+ into `examples/`, using the matching updated SDK build.
97
135
  Copy `examples/.env.example` to `.env` in the directory you will run commands from:
98
136
 
99
137
  ```sh
@@ -109,24 +147,129 @@ LAUNCH_API_URL=
109
147
  RPC_URL=
110
148
  ```
111
149
 
112
- Set `PRIVATE_KEY` to **your funded EOA's** 32-byte hex key and `LAUNCH_API_URL` to
113
- your actual HTTPS or owned loopback API service root. There is no default wallet,
114
- public development key, guessed API URL, or silent API skip. The API needs actual
150
+ Configure **exactly one** signer: your funded EOA's 32-byte `PRIVATE_KEY`, or
151
+ `EXAMPLE_KEYSTORE_PATH` pointing to a local V3 scrypt/AES-128-CTR JSON keystore.
152
+ `EXAMPLE_KEYSTORE_PASSWORD` defaults to the empty string; both/neither signer
153
+ sources reject. The keystore must be a regular owner-only file owned by your user;
154
+ the bounded loader authenticates its Keccak MAC and declared address before deriving
155
+ the creator. It uses Node crypto and existing viem, with no extra dependency.
156
+ Dry-run configuration derives only the public creator address; signing methods are
157
+ constructed only in broadcast or nonterminal resume execution.
158
+ Never commit the keystore/password or use a published test key for a real launch.
159
+ Set `LAUNCH_API_URL` to your actual HTTPS or owned loopback service root. There is
160
+ no default wallet, guessed metadata API, or silent API skip. The API needs actual
115
161
  application storage and an indexer observing the same chain as the execution RPC.
116
162
  Existing environment variables take precedence over the working-directory `.env`,
117
163
  loaded once using Node's native `process.loadEnvFile`. No shell interpolation is used.
118
164
 
165
+ `EXAMPLE_BUY_AMOUNT_WEI` sets the exact **native ETH conversion input per opening
166
+ buy**, not the eventual WETH/USDG amount. Use a positive canonical decimal uint256
167
+ wei string; the default is `10000000000000` (**0.00001 ETH**). Kyber's app-compatible
168
+ exact-input domain additionally requires each aggregate input to be below `2^255`.
169
+ The runner aggregates ETH inputs per quote, obtains one fresh
170
+ `POST EXAMPLE_KYBER_API_URL/api/v1/quote/kyber/build?chainId=4663` build per quote,
171
+ and binds native zero-address input, exact input, sender/recipient equal to the
172
+ actual funding escrow, **50 bps conversion slippage**, and the same 300-second
173
+ launch-purpose deadline as the plan. The API owns fresh route preview; a preview
174
+ GET is not executable funding. `EXAMPLE_KYBER_API_URL` defaults to `LAUNCH_API_URL`
175
+ (the app's public trade default is `https://api.abyss.trading`); an explicit override
176
+ must meet the same HTTPS/owned-loopback safety rules.
177
+
178
+ Each funding row is `LifecycleFundingKind.Swap`, native zero-address `inputAsset`,
179
+ the reviewed router target and original built calldata. The runner decodes the
180
+ reviewed `swap` entry point and checks currencies, escrow recipient, exact input,
181
+ output floor, executor payload, flags and absence of redirected inputs/extra fees.
182
+ `amountOutMinimum = floor(amountOut * 9950 / 10000)` is the exact quote budget.
183
+ That budget is divided across the quote's ordered buys, with the integer remainder
184
+ in the last such buy, so their inputs sum exactly to the API minimum. No WETH/USDG
185
+ wallet balance or ERC20 approval is needed; the creator needs native ETH **plus gas**.
186
+ Registry target/spender/runtime admission is checked on the launch graph and
187
+ rechecked before signatures. Refusal, unavailable route, changed binding or expiry
188
+ stops unsigned with retained evidence: **never fall back to native-wrap, direct ERC20
189
+ funding, a separate wallet swap, dropped buys, or rewritten quote bytes/deadline**.
190
+
191
+ Optional `EXAMPLE_TOKEN_NAME`, `EXAMPLE_TOKEN_SYMBOL`, and
192
+ `EXAMPLE_TOKEN_DESCRIPTION` override each case's default metadata. Text is NFC
193
+ normalized and trimmed, with the unchanged API/lifecycle bounds (name: 100 Unicode
194
+ codepoints/128 UTF-8 bytes; symbol: 32 codepoints/bytes; description: 2000 codepoints).
195
+ `EXAMPLE_IMAGE_PATH` optionally loads 1 byte through 5 MiB of actual PNG/JPEG/WebP
196
+ bytes. The frozen image SHA-256/type/length is reviewed and signed, uploaded using
197
+ only the exact API-issued PUT URL/headers, and completed/verified before execution.
198
+ Without it the session remains metadata-only; no artwork is invented. API image
199
+ verification may reject malformed or animated files even when their type is valid.
200
+ With an image set, success additionally requires matching staged/published image
201
+ SHA-256/type/length, the same non-null public image URL in the publication and
202
+ indexed token DTO, and one bounded no-redirect GET of that URL returning **HTTP
203
+ 200**, an image content-type family and nonempty bytes. Byte-identical output
204
+ must match the signed type/length/SHA-256. Different served bytes may be an API/CDN
205
+ transformation: `published-image.json` records the actual SHA-256/type/length and
206
+ that limited family/nonempty-body check, explicitly not byte identity. HTTP/type/
207
+ empty/oversized failures stop nonzero with evidence; no image retry or metadata-only
208
+ fallback occurs. The final canonical RPC barrier runs after this GET.
209
+
210
+
211
+ The target is **USD 5000**, not a fixed token/WETH ratio. Optional
212
+ `EXAMPLE_TARGET_MARKET_CAP_USD` accepts a positive exact USD decimal (up to 18
213
+ fractional digits). It does not grant signing permission or override the USD seed.
214
+ The runner makes one bounded, uncached GET to
215
+ `LAUNCH_API_URL/api/v1/token-prices?chainId=4663&limit=100`, without pagination,
216
+ redirects or retries. It selects the reviewed chain-4663 WETH address and requires
217
+ ready metadata, 18 decimals, `priced: true`, `source: "anchor"`, and direct
218
+ Chainlink-anchor provenance bound to WETH and the reviewed aggregator
219
+ `0x78F3556b67E17Df817D51Ef5a990cDaF09E8d3A9`. The exact positive uint256
220
+ `priceUsdX18` is an **indicative API-published launch seed**, not an executable
221
+ swap quote or on-chain execution authority. HTTP/body/validation failure or a missing
222
+ WETH row stops unsigned; there is no manual price or alternate-source fallback.
223
+ Each request has a 30-second timeout and a 1 MiB streamed response limit.
224
+ The review and console preserve API origin, index/graph blocks, upstream observation
225
+ timestamp and age, and local retrieval time. Retrieval does not make an old upstream
226
+ observation fresh. The API may continue publishing its price as upstream age grows;
227
+ the runner does not impose a 15-minute contract-round freshness gate.
228
+ USDG markets use the SDK-exported chain-4663 Global Dollar address, **6 decimals**
229
+ and the reviewed `usdPeg` source at exactly `1e18` USD-X18, matching the app. There
230
+ is no substituted WETH/USD value. Every market has its own quote precision, USD
231
+ seed, token/quote orientation and aligned valuation; multi-quote FDVs are not additive.
232
+
233
+
234
+ Before any attribution or transaction signature, the runner saves
235
+ `economic-review.json` and exact owner-only recovery and prints its financial summary.
236
+ The computed hash binds all quotes, target, actual supply, predicted per-market
237
+ token order, every allocation, fees, protected buys, Kyber conversion bytes/minima/
238
+ deadline, metadata/image and finalized plan. It is provenance evidence, never an
239
+ authorization input. Dry runs stop here without signing; broadcast runs save
240
+ `economic-admission.json` with `authorization: "--broadcast"` and that hash as
241
+ evidence of the chosen mode, not another gate.
242
+ Before every later signature the runner rereads the same configured API snapshot and
243
+ rechecks the immutable review, target, supply, finalized plan and predicted token
244
+ order. Any exact price, API origin, chain, WETH/decimals or direct-anchor identity,
245
+ kind or source change stops execution. Failed or unpriced reads also reject.
246
+ Index/graph blocks and observation/retrieval times may advance with the identical
247
+ price and source; they never replace the original review. Changed economics require
248
+ a new explicit review, never silent plan rewriting or submission replay. Actual
249
+ RPC chain, balances, nonce, prediction, deadline and native execution proof remain
250
+ execution authority; API block fields are observations, not RPC canonicality pins.
251
+ The original plan deadline must still be future at metadata signing/staging and
252
+ before each later signature, including **after asynchronous quote/authority reads**.
253
+ Expiry requires a new explicit review; the runner never extends the saved deadline.
254
+
255
+
119
256
  Blank `RPC_URL` uses the SDK official Robinhood chain-4663 mainnet endpoint; HTTPS
120
257
  providers and explicit owned loopback HTTP execution RPCs are supported.
121
- The creator is derived locally from the key, and the deployment/WETH addresses come
122
- from `getAddresses(4663)`. The runner checks chain identity, EOA, deployed core and
123
- its configured registry binding, discovers admitted profiles, verifies the funding
124
- escrow core/wrapped-native binding and reads the registered P1 `(1,4096)` oracle
125
- configuration. No fixture defines these facts. V4 fixed cases require config6/V2;
126
- an old config5 profile is not silently selected instead.
127
- V4 fixed cases now encode max `10000`, min `1000` pips and sensitivity `7654321`
128
- fee-pips × seconds/tick; all are immutable. The current defaults resolve the matching
129
- October8 mined config6 graph. Position maxima exactly cover market budgets and budgets
258
+ The creator is derived locally from the configured signer; deployment/WETH addresses
259
+ come from `getAddresses(4663)`. The runner checks chain identity, EOA, deployed core
260
+ and registry, admitted profiles, funding escrow/core/native binding and each quote's
261
+ actual decimals. WETH keeps the registered P1 `(1,4096)` oracle. USDG discovers
262
+ `OracleConfigRegistered` history at a pinned block, rereads the factory mapping at
263
+ that same block, and selects a compatible registered config deterministically by
264
+ increasing max tick move, decreasing cardinality, then config ID. Factory configs
265
+ are generic, not a separate hardcoded USDG ID. No compatible config, unavailable
266
+ history, or a changed canonical pin fails loudly. V4 cases require config6/V2;
267
+ an old config5 profile is never selected instead.
268
+ V4 fixed cases encode max `10000`, min `1000` pips and sensitivity `7654321`
269
+ fee-pips × seconds/tick; all are immutable. The reviewed `FixedFeePoolHookV1` charges
270
+ the fixed maximum `10000` pips (1%) on applicable amounts. Minimum and sensitivity
271
+ are stored and exposed, not used for a dynamic fee calculation. The current defaults
272
+ resolve the matching October8 mined config6 graph. Position maxima exactly cover market budgets and budgets
130
273
  exactly cover minted supply. Actual unused inventory burns before buys, never to the
131
274
  creator. Verification accounts for burn `Transfer` logs, reduced `totalSupply`, an
132
275
  empty core token balance, and creator balance equal only to paid opening-buy output.
@@ -143,17 +286,24 @@ the saved `reviewedTransaction` and preflighted read-only through the same execu
143
286
  RPC before signing. Calldata, value, gas and gas price must remain exactly as reviewed.
144
287
  There is no mode fallback, admission override, automatic submission replay or reduced case.
145
288
 
146
- ### Commands and fixed cases
289
+ ### Commands and launch matrix
290
+
291
+ Every command below defaults to a dry run. Append `--broadcast` to execute the
292
+ selected case; the table's atomic/staged mode is independent of the CLI dry-run/
293
+ broadcast choice.
147
294
 
148
295
  ```sh
149
- node examples/launch-erc20-v4.mjs
150
- node examples/launch-erc20-abyss.mjs
151
- node examples/launch-erc404-v4.mjs
152
- node examples/launch-erc404-abyss.mjs
153
- node examples/launch-erc20-staking-v4.mjs
154
- node examples/launch-erc20-dividends-abyss.mjs
155
- node examples/launch-erc20-burn-mixed.mjs
156
- node examples/launch-erc404-dividends-mixed.mjs
296
+ node examples/launch-erc20-v4.ts
297
+ node examples/launch-erc20-abyss.ts
298
+ node examples/launch-erc404-v4.ts
299
+ node examples/launch-erc404-abyss.ts
300
+ node examples/launch-erc20-staking-v4.ts
301
+ node examples/launch-erc20-dividends-abyss.ts
302
+ node examples/launch-erc20-burn-mixed.ts
303
+ node examples/launch-erc404-dividends-mixed.ts
304
+ node examples/launch-erc20-multi-quote.ts
305
+ node examples/launch-erc20-depth-v4.ts
306
+ node examples/launch-erc20-dividends-multiquote-mixed.ts
157
307
  ```
158
308
 
159
309
  | File suffix | Token / rewards | Markets and permanent positions | Mode / opening buys |
@@ -166,10 +316,30 @@ node examples/launch-erc404-dividends-mixed.mjs
166
316
  | `erc20-dividends-abyss` | ERC20 / dividends | Abyss: 3 | staged / 1 |
167
317
  | `erc20-burn-mixed` | ERC20 / token-only burn 3000 bps | dual-fee V4: 2; Abyss: 1 | staged / 1 per market |
168
318
  | `erc404-dividends-mixed` | ERC404 / dividends | V4: 2; Abyss: 3 | staged / 1 per market |
319
+ | `erc20-multi-quote` (new) | ERC20 / none | V4 WETH: 1; V4 USDG: 1; Abyss WETH: 1 | staged / 1 per market (3 total) |
320
+ | `erc20-depth-v4` (new) | ERC20 / none | V4 WETH: 4, Early Scarcity / progressive Depth | staged / 1 |
321
+ | `erc20-dividends-multiquote-mixed` (new) | ERC20 / dividends 4000 bps | V4 WETH: 2; V4 USDG: 2; Abyss WETH: 3 | staged / 1 per market (3 total) |
322
+
323
+ The three new cases are **additions**, not replacements yet: the eight existing
324
+ descriptors/topologies remain intact until the user validates new cases with real
325
+ runs. At most one V4 market per quote is permitted; Abyss may reuse a quote.
169
326
 
170
327
  ERC20 supply is `1_000_000e18`; ERC404 supply is `10_000e18`, NFT unit `100e18`.
171
- Positions retain `1000e18` liquidity and the case's exact ranges. Each ordered buy
172
- spends up to `0.001 ETH` through native-wrap funding. The unified SDK invocation sets
328
+ `deriveLaunchPoolRecipe` prices against **the entire actual minted supply**, even
329
+ in mixed-market cases. Per-market budgets divide that supply, with integer remainder
330
+ assigned to the last market. One position uses the recipe's full one-sided range
331
+ and budget-funded liquidity; multi-position markets use `deriveLaunchPositionRanges`
332
+ with the exact requested count, `positionGaps: "adjacent"` and an explicitly
333
+ extended final tail. Staircase remains the existing multi-position default; the
334
+ new four-position Depth case uses **Early Scarcity**, increasing inventory from
335
+ low-price scarcity to more inventory at higher prices. This is the requested Depth
336
+ shape in the current SDK vocabulary, not a literal reproduction of the separate
337
+ eight-position design catalogue. Spacing is 60 and LP fee is 3000 pips for both
338
+ venues. Predicted address order sets orientation independently per quote; multi-quote
339
+ markets aim at the same USD valuation, not the same raw sqrt price. Per-position
340
+ maxima exactly cover each budget, except documented integer mint-rounding dust.
341
+ Each buy defaults to `0.00001 ETH` through its quote's Kyber funding conversion.
342
+ The unified SDK invocation sets
173
343
  every ordered buy's minimum from its actual stateful diagnostic output with **50 bps
174
344
  (0.5%) slippage**, then proves and saves only the final protected commitment. The draft's
175
345
  one-wei minima are diagnostic inputs, never the submitted protection.
@@ -180,11 +350,17 @@ Hook salts/random identities are finalized and saved before execution. The share
180
350
  runner uses the combined preparation/admission result without an immediate second
181
351
  planning pass. Staged cases simulate only staged work, never an unused atomic launch.
182
352
 
183
- These are deliberately simple fixed-geometry consumer cases, not an FDV recipe:
184
- equal position maxima partition each market budget exactly, while fixed liquidity
185
- can spend less than those maxima. Consequently actual unused inventory can be
186
- substantial, not merely one rounding unit. It burns; it is not creator inventory.
187
- Use SDK pool/position recipe helpers when you need valuation-driven allocation.
353
+ USD 5000 is a **target before tick alignment**, not a promise of exactly USD 5000
354
+ after alignment or buys. The economic review shows aligned unit price in USD/quote,
355
+ minted-supply valuation, expected rounding burn, retained supply and its aligned
356
+ opening valuation. It also decodes every ordered output/input from the final admitted
357
+ simulation receipt, showing all-in average execution price and the premium against
358
+ opening price. That premium includes fees and price impact; it is **not** the
359
+ post-buy marginal spot price. Opening buys move the pool, so the actual post-buy
360
+ valuation must use observed post-activation pool price and retained total supply.
361
+ The old 1:1/fixed-liquidity examples could burn almost the entire intended supply
362
+ and produce a radically different retained-supply valuation. They are not a pricing
363
+ recipe or a valid precedent for a new launch.
188
364
 
189
365
  ### Optional execution restrictions
190
366
 
@@ -199,43 +375,90 @@ Poster allocation is already inside Nitro gas/affordability and is not charged t
199
375
 
200
376
  ### Evidence and failure recovery
201
377
 
202
- Each run automatically creates `launch-results/<timestamp-case-random>/`; there is
203
- no user output option. Inspect `result.json`, `events.jsonl`, finalized `plan.json`,
204
- `receipts.json` and `published-token.json`. Exact admitted wallet envelopes are signed
205
- locally; computed hashes and unsigned envelopes are durably retained as
206
- `broadcast-attempt` **before the one raw broadcast**. Real receipts are saved before
378
+ Each dry run or broadcast automatically creates `launch-results/<timestamp-case-random>/`;
379
+ `--resume` reuses the original directory rather than creating another launch. Inspect
380
+ `result.json`, `events.jsonl`, finalized `plan.json`, `planning.json`,
381
+ `economic-review.json` and `receipts.json`. A dry-run result has `runMode: "dry-run"`,
382
+ `scope: "planning"` and `execution: "dry-run"`, with no transactions or API writes.
383
+ Publication-only artifacts (`publication-progress.json`, `published-token.json` and,
384
+ when configured, `published-image.json`) are produced only during broadcast/resume.
385
+ Exact admitted wallet envelopes are signed locally only during execution; computed
386
+ hashes and unsigned envelopes are durably retained as `broadcast-attempt`
387
+ **before the one raw broadcast**. Real receipts are saved before
207
388
  status/canonical-state assertions. No unlocked-account signing or sending is used.
208
- Public evidence redacts known keys, signatures, signed raw bytes, API capabilities,
209
- authorization values and RPC endpoint credentials. Only `private-recovery.json`
210
- (mode `0600`) retains raw signed transactions and one-time API recovery material;
211
- never share or commit it. `launch-results/` is ignored.
212
-
213
- Every case requires actual API metadata staging, publication using the activation
214
- hash, and an indexed DTO matching token/creator/hash/metadata. Genuine pending-indexer
215
- HTTP `202` responses are polled for up to 90 seconds respecting `Retry-After`;
216
- other API failures are not retried or converted to partial success. Broadcast/API
217
- failures retain logs/hashes and exit nonzero. The runner never retries a raw send,
218
- relaunches, cancels or rolls back the source chain. **Do not blindly rerun after an
219
- ambiguous broadcast**: inspect the durable transaction hash on chain first.
389
+ Public evidence preserves structured field names but redacts sensitive values:
390
+ known keys, signatures, signed raw bytes, API capabilities, authorization values
391
+ and endpoint credentials. Public `plan.json` may therefore differ from the exact
392
+ commitment and is **not recovery authority**. Before the first attribution or chain
393
+ signature, `private-recovery.json` durably retains the complete unredacted finalized
394
+ `plan`, original `mode`, `confirmations` and `economicReview`. Broadcast additionally
395
+ saves `economicAdmission` with the computed review hash and `authorization: "--broadcast"`.
396
+ This owner-only file (mode `0600` inside the mode `0700` run directory) also retains
397
+ raw signed transactions and one-time API recovery material across session updates.
398
+ Original plan and economic review/admission provenance are immutable.
399
+ Never share or commit it.
400
+ `launch-results/` is ignored.
401
+
402
+ Every broadcast case requires actual API metadata staging (and verified image completion
403
+ when configured), publication using the activation hash, and an indexed DTO
404
+ matching token/creator/hash/metadata/image. Genuine pending-indexer HTTP `202`
405
+ responses are polled for up to 90 seconds respecting `Retry-After`. Before **each
406
+ publication attempt** and before final success, fresh RPC progress must be
407
+ confirmation-safe canonical Active with all retained receipts confirmed and the
408
+ original activation still in its saved block number/hash. Reorg, moved inclusion,
409
+ missing/unconfirmed receipt or changed phase stops, retains `publication-progress.json`
410
+ and private recovery evidence, and exits nonzero—even if the API reports success.
411
+ Other API failures are not retried or converted to partial success. The runner
412
+ never retries a raw send, relaunches, cancels or rolls back the source chain.
413
+ **Do not blindly rerun after an ambiguous broadcast**: inspect the durable hash first.
220
414
  See [chain/API invariants](../docs/launch-lifecycle.md#individual-token-creation-examples).
221
415
 
416
+ Continue a begun launch with the same signer source and API endpoint:
417
+
418
+ ```sh
419
+ node examples/launch-erc20-v4.ts --resume launch-results/<original-run-directory>
420
+ ```
421
+
422
+ All eleven wrappers accept this option; the retained plan/review, not the wrapper's
423
+ case descriptor or new identity overrides, determines the resumed launch.
424
+ The runner loads owner-only `private-recovery.json`, restores the original mode,
425
+ confirmation policy, execution restrictions and typed receipts with observed block
426
+ number/hash, and re-admits `parseLaunchPlan(JSON.stringify(recovery.plan))` with
427
+ `planLaunch` against current canonical state. It does **not** call
428
+ `prepareAndPlanLifecycleLaunch`, remine salts, recalibrate buys, or repeat begin.
429
+ Canonical **Preparing/Ready** resumes only remaining `buildNextTransaction` steps
430
+ under the saved economic admission and signing gates; canonical **Active** recovers
431
+ the original activation receipt and runs chain verification/publication only,
432
+ including after the signing deadline. Unstarted/Cancelled state, changed inclusion,
433
+ replacement or unresolved signed hashes stop for read-only reconciliation.
434
+
435
+ Before publication the original API session is refreshed with `getUploadSession`;
436
+ the retained one-time capability is carried across every read/renew/complete response
437
+ because the API does not echo it. If an image is still awaiting upload, set
438
+ `EXAMPLE_IMAGE_PATH` to the original bytes: SHA-256, content type and length must
439
+ match the signed descriptor. An expired PUT URL is renewed once on HTTP 403/410/412
440
+ with `renewUploadUrl`, then the same bytes are uploaded and completed. A live ready
441
+ image is never reuploaded. No new attribution signature or session is created.
442
+ All existing chain/image/indexer checks and canonical activation barriers still apply.
443
+
222
444
  After interruption, timeout, replacement or reorg, preserve the original identity,
223
- final `plan.json`, selected mode, confirmation policy and every signed hash. Do not
224
- deserialize diagnostic `planning.json` as a trusted `PlannedLaunch`, remine salts,
225
- recalibrate buys or restart a wrapper. Reconstruct the exact saved commitment with
226
- `planLaunch`, then use `readLaunchProgress` and fresh `buildNextTransaction` on the
227
- intended source RPC. Supply receipt references including observed block number/hash;
445
+ `private-recovery.json` and every signed hash. Public `plan.json` and diagnostic
446
+ `planning.json` are not recovery authority; do not rerun a wrapper without `--resume`.
447
+ Supply receipt references including observed block number/hash;
228
448
  when a replacement is known retain both `transactionHash` (original) and
229
449
  `replacementHash` (effective). A same-nonce cancellation is not successful activation;
230
450
  a missing receipt alone does not prove a reorg. No replacement is adopted or retried
231
451
  automatically by these local-signing cases: a timed-out original hash requires manual
232
- reconciliation. `launch.mjs` provides the unsigned reload/review path. Recovery of API
233
- publication uses the original private session/capability and canonical activation
234
- hash, never another launch.
452
+ reconciliation. `launch.ts` provides unsigned reload/review for a privately extracted
453
+ exact plan: keep that file owner-only and supply the original `--mode`,
454
+ `--confirmations` and reconciled `--receipts`. Do not publish the extracted plan or
455
+ CLI output, which may contain sensitive committed values. Recovery of API publication
456
+ uses the original private session/capability and canonical activation hash, never
457
+ another launch.
235
458
 
236
459
  ### Owned-local wallet verification helpers
237
460
 
238
- `launch-example-support.mjs` exports
461
+ `launch-example-support.ts` exports
239
462
  `createLocalLaunchWallet({privateKey,creator,chainId,orchestrator,client,redactor})`
240
463
  and `submitSignedRecorded({transaction,wallet,client,wait,artifacts,signal})`.
241
464
  `client.request({method,params})` is an explicit RPC adapter; `transaction` carries
@@ -245,10 +468,14 @@ The signer exposes `address`, `signTypedData(typedData)` and `signTransaction(wi
245
468
  returning `{wire,rawTransaction,transactionHash}`. Retain the result privately.
246
469
  Use `RunArtifacts(output,caseId,redactor)` with `Redactor` and a fresh directory for
247
470
  durable evidence; call `initialize()` before work and `finish(status,error)` afterward.
248
- The shared `runLaunchExample(caseObject)` in `launch-example.mjs` takes the same fixed
249
- case objects as the eight files, loads environment and auto-creates its output.
250
- Offline diagnostic tests are in `test/launch-example.test.mjs`; they do not claim
251
- real launch or API-indexer proof.
471
+ The shared `runLaunchExample(caseObject, argv = process.argv.slice(2))` in
472
+ `launch-example.ts` takes the same fixed case objects as the eleven files, loads
473
+ environment and either auto-creates output for a new launch or resumes in place.
474
+ `RunArtifacts(output,caseId,redactor,{resume:true})` reopens private recovery and
475
+ retained transaction evidence without truncating the journal.
476
+ Offline diagnostics are in `test/launch-example.test.mjs`,
477
+ `test/launch-example-matrix.test.mjs` and `test/launch-example-resume.test.mjs`;
478
+ they do not claim real launch/indexer proof.
252
479
 
253
480
  ## Relationship to the application flows
254
481
 
@@ -256,8 +483,9 @@ The examples have been reviewed against `abyss-app`'s `scripts/launch-node.mjs`,
256
483
  `launch-node-deploy.mjs`, `launch-browser-wallet.mjs`, `launch-staged-smoke.mjs`,
257
484
  `launch-review-smoke.mjs`, and `src/lib/creation` / `src/lib/lifecycle` authoring,
258
485
  funding, execution and recovery modules. These are behavioral references, not SDK
259
- dependencies. That application's `black-market-sdk-0.7.0-local-20261007.tgz` pin and
260
- October5 address literals are **not** current deployment authority. The mined graph
486
+ dependencies. The application consumes the published **`@black-market/sdk` 0.8.0** and
487
+ derives current deployment defaults through **`getAddresses`**, as do these examples.
488
+ The package pin alone is not live deployment authority. The mined graph
261
489
  is recorded in the contracts repository at
262
490
  `contracts/deployments/launch/pool-launch-v1/20261008T000141Z-e174ce6/manifest.json`;
263
491
  examples resolve its SDK presets and certify live bindings, rather than copying
@@ -265,13 +493,13 @@ addresses from an application script.
265
493
 
266
494
  | Flow | Shared contract / intentional difference |
267
495
  | --- | --- |
268
- | Eight fixed launch wrappers | Unified preparation/admission, explicit mode, exact allocations, immutable config6 max/min/sensitivity, protected ordered buys, reviewed next envelopes and canonical Active/custody verification. All eight remain independent no-argument cases. |
269
- | App Node launch/deploy | Uses valuation-driven recipe positions and native-to-ERC20 conversion quotes. Fixed cases intentionally use one registered wrapped-native quote and `NativeWrap`; there is no conversion API, router calldata or quote-expiry dependency. |
496
+ | Eleven launch wrappers | Unified preparation/admission, explicit mode, exact allocations, immutable config6 fees, protected ordered buys, reviewed next envelopes and canonical Active/custody verification. Eight original descriptors remain; three new matrix additions await user live validation. |
497
+ | App Node launch/deploy | Both use valuation-driven recipes with actual supply, per-quote orientation/budgets and native ETH-to-quote Kyber funding. Examples retain an indicative validated API WETH USD seed and the reviewed USDG peg; they default to a dry run, while `--broadcast` supplies explicit authorization independently of mandatory RPC execution proof. |
270
498
  | Browser wallet | Browser account/provider authority and explicit UI review are application-owned. The examples instead derive an EOA locally, hold one source/submission RPC, recheck chain before signing/sending, and preserve computed signed hashes before one raw send. A browser integration must bind the active account/provider/chain again after review and pass that provider's RPC adapter as `submissionClient`; read proof alone does not authorize wallet submission. |
271
- | App creation funding | Native wrapping needs ETH value, not an ERC20 approval. Direct ERC20 funding needs balance/allowance to the **actual core-owned funding escrow**, not an arbitrary router/core. ERC20-input conversions additionally need registry-admitted inputs, a registered target/spender/runtime, exact receiver/calldata/minimum/precision, and a fresh unexpired quote. Use SDK prerequisites and fresh `approve-reset` / `approve` next steps; do not extend the fixed runner's native-only signing allowlist blindly. |
272
- | App metadata/image | Fixed cases sign the same chain/core/wallet-bound attribution and stage metadata only: `image: null`, session `ready_to_launch`, no image upload claim. For a real image, hash the actual bytes, sign its descriptor, use `putImage` with the issued upload URL/headers, and `completeUpload` before launch. App legal consent, API catalogs and keystore handling are not generic SDK implementations to copy. |
273
- | App publication/recovery | Pending HTTP 202 is not success. Fixed cases honor `LaunchPublishPending`/`Retry-After` within a bounded deadline and require ready metadata plus the indexed token/creator/activation DTO. The app's Query polling/UI, two-confirmation policy and replacement tracking are intentionally different from the fixed examples' one-confirmation, stop-and-reconcile local signer. |
274
- | App review/staged smoke | These app scripts exercise read-only browser review and large matrices, not permission to deploy. SDK `quickstart.mjs` and `launch.mjs` remain read-only on the source chain. SDK `launch-lifecycle-smoke.mjs` is a different, explicitly authorized owned-loopback execution proof, including real ERC20 approval prerequisites when supplied by fixture plans. |
499
+ | App creation funding | All fixed examples use integrated native-input `Swap` funding. Current registry target/spender/code hash, native/quote precision and decoded exact receiver/input/minimum/calldata are checked. No separate swap, native-wrap fallback or ERC20 approval is submitted on refusal. Other app payment paths are not this example runner's signing allowlist. |
500
+ | App metadata/image | Both sign chain/core/wallet-bound attribution. Optional `EXAMPLE_IMAGE_PATH` signs actual SHA-256/type/length, uses the exact issued `putImage` URL/headers and requires `completeUpload` verification before launch. Publication/indexed association and one bounded public image GET are also required before example success; transformed served bytes are recorded separately. Unset keeps metadata-only behavior. Signer may be a local key or authenticated V3 keystore; app legal/UI consent remains application-owned. |
501
+ | App publication/recovery | Pending HTTP 202 is not success. Examples honor `LaunchPublishPending`/`Retry-After` and require indexed provenance plus fresh confirmation-safe RPC Active and the original activation inclusion before every attempt/final pass. The app's polling UI/two-confirmation/replacement policy differs intentionally from these one-confirmation stop-and-reconcile examples. |
502
+ | App review/staged smoke | These app scripts exercise read-only browser review and large matrices, not permission to deploy. SDK `quickstart.ts` and `launch.ts` remain read-only on the source chain. SDK `launch-lifecycle-smoke.ts` is a different, explicitly authorized owned-loopback execution proof, including real ERC20 approval prerequisites when supplied by fixture plans. |
275
503
  | Historical commitment generator | Retains original independent config4 bytes/hashes for codec regression evidence; no addresses or allocations in that vector should be used to construct the current graph. |
276
504
 
277
505
  ### Safe verification without a funded launch
@@ -282,11 +510,11 @@ chain/account, exact-signing, redaction, pre-broadcast durability, pending-publi
282
510
  and no-retry behavior, plus residual-burn/no-creator-reserve accounting; they do not
283
511
  claim an actual chain launch or indexer proof.
284
512
 
285
- For CLI proof, run `node examples/launch.mjs` without required arguments (usage refusal,
286
- no RPC/signing) and `node examples/generate-lifecycle-commitment-fixture.mjs` without
513
+ For CLI proof, run `node examples/launch.ts` without required arguments (usage refusal,
514
+ no RPC/signing) and `node examples/generate-lifecycle-commitment-fixture.ts` without
287
515
  output paths (offline historical vector to stdout). Read-only deployed discovery is
288
- `node examples/quickstart.mjs`. With a reviewed exact saved current plan, use
289
- `launch.mjs --plan ... --rpc ... --mode ...` and retained receipt-reference JSON;
516
+ `node examples/quickstart.ts`. With a reviewed exact saved current plan, use
517
+ `launch.ts --plan ... --rpc ... --mode ...` and retained receipt-reference JSON;
290
518
  `--mine` performs only local mining and read-only native simulation on the source.
291
519
  Do **not** run any of the eight configured wallet/API wrappers to verify this review.
292
520
  Real metadata-session integration needs an owned disposable HTTP service; full custody,
@@ -305,7 +533,7 @@ pnpm build
305
533
  LAUNCH_LIFECYCLE_RPC_URL=http://127.0.0.1:18555 \
306
534
  LAUNCH_LIFECYCLE_FORK_RPC_URL=http://127.0.0.1:18556 \
307
535
  LAUNCH_LIFECYCLE_ALLOW_LOCAL_EXECUTION=1 \
308
- node examples/launch-lifecycle-smoke.mjs manifest.json sdk-plans.json
536
+ node examples/launch-lifecycle-smoke.ts manifest.json sdk-plans.json
309
537
  ```
310
538
 
311
539
  This explicitly authorized command executes disposable fixture transactions and
@@ -1,4 +1,4 @@
1
- import { runLaunchExample } from "./launch-example.mjs";
1
+ import { runLaunchExample } from "./launch-example.ts";
2
2
 
3
3
  await runLaunchExample({
4
4
  id: "erc20-abyss-basic", description: "ERC20, one canonical Abyss position, atomic opening",
@@ -1,4 +1,4 @@
1
- import { runLaunchExample } from "./launch-example.mjs";
1
+ import { runLaunchExample } from "./launch-example.ts";
2
2
 
3
3
  await runLaunchExample({
4
4
  id: "erc20-burn-mixed", description: "Burn policy, dual-fee V4 and Abyss markets for one token",
@@ -0,0 +1,7 @@
1
+ import { runLaunchExample } from "./launch-example.ts";
2
+
3
+ await runLaunchExample({
4
+ id: "erc20-depth-v4", description: "ERC20 Depth shape: four adjacent Early Scarcity positions with increasing inventory and a permanent final tail",
5
+ tokenKind: 0, rewardMode: 0, mode: "staged",
6
+ markets: [{ venue: "v4", positions: 4, distributionPreset: "early-scarcity" }], buysPerMarket: 1,
7
+ });
@@ -1,4 +1,4 @@
1
- import { runLaunchExample } from "./launch-example.mjs";
1
+ import { runLaunchExample } from "./launch-example.ts";
2
2
 
3
3
  await runLaunchExample({
4
4
  id: "erc20-dividends-abyss", description: "Holder dividends and three canonical Abyss positions",
@@ -0,0 +1,8 @@
1
+ import { runLaunchExample } from "./launch-example.ts";
2
+
3
+ await runLaunchExample({
4
+ id: "erc20-dividends-multiquote-mixed", description: "ERC20 holder dividends, two quotes, both venues, seven permanent positions and three opening buys",
5
+ tokenKind: 0, rewardMode: 2, mode: "staged",
6
+ markets: [{ venue: "v4", quote: "WETH", positions: 2 }, { venue: "v4", quote: "USDG", positions: 2 },
7
+ { venue: "abyss", quote: "WETH", positions: 3 }], buysPerMarket: 1,
8
+ });
@@ -0,0 +1,8 @@
1
+ import { runLaunchExample } from "./launch-example.ts";
2
+
3
+ await runLaunchExample({
4
+ id: "erc20-multi-quote", description: "ERC20, two quotes, two pool-bound V4 markets and one Abyss market",
5
+ tokenKind: 0, rewardMode: 0, mode: "staged",
6
+ markets: [{ venue: "v4", quote: "WETH", positions: 1 }, { venue: "v4", quote: "USDG", positions: 1 },
7
+ { venue: "abyss", quote: "WETH", positions: 1 }], buysPerMarket: 1,
8
+ });
@@ -1,4 +1,4 @@
1
- import { runLaunchExample } from "./launch-example.mjs";
1
+ import { runLaunchExample } from "./launch-example.ts";
2
2
 
3
3
  await runLaunchExample({
4
4
  id: "erc20-staking-v4", description: "Staking rewards, two V4 positions and two ordered opening buys",
@@ -1,4 +1,4 @@
1
- import { runLaunchExample } from "./launch-example.mjs";
1
+ import { runLaunchExample } from "./launch-example.ts";
2
2
 
3
3
  await runLaunchExample({
4
4
  id: "erc20-v4-basic", description: "ERC20, one pool-bound V4 position, atomic opening",