@black-market/sdk 0.4.0 → 0.5.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 +128 -149
- package/assets/splash.png +0 -0
- package/dist/addresses.d.ts +3 -1
- package/dist/addresses.d.ts.map +1 -1
- package/dist/addresses.js +23 -17
- package/dist/addresses.js.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/launch-api.d.ts +2 -1
- package/dist/launch-api.d.ts.map +1 -1
- package/dist/launch-api.js +2 -1
- package/dist/launch-api.js.map +1 -1
- package/dist/lifecycle/abi.d.ts +1246 -292
- package/dist/lifecycle/abi.d.ts.map +1 -1
- package/dist/lifecycle/abi.js +106 -12
- package/dist/lifecycle/abi.js.map +1 -1
- package/dist/lifecycle/progress.js +9 -9
- package/dist/lifecycle/progress.js.map +1 -1
- package/dist/lifecycle/schema.d.ts +3 -4
- package/dist/lifecycle/schema.d.ts.map +1 -1
- package/dist/lifecycle/schema.js +3 -4
- package/dist/lifecycle/schema.js.map +1 -1
- package/docs/launch-lifecycle.md +199 -41
- package/examples/.env.example +20 -0
- package/examples/README.md +223 -0
- package/examples/generate-lifecycle-commitment-fixture.mjs +49 -0
- package/examples/launch-erc20-abyss.mjs +7 -0
- package/examples/launch-erc20-burn-mixed.mjs +7 -0
- package/examples/launch-erc20-dividends-abyss.mjs +7 -0
- package/examples/launch-erc20-staking-v4.mjs +7 -0
- package/examples/launch-erc20-v4.mjs +7 -0
- package/examples/launch-erc404-abyss.mjs +7 -0
- package/examples/launch-erc404-dividends-mixed.mjs +7 -0
- package/examples/launch-erc404-v4.mjs +7 -0
- package/examples/launch-example-support.mjs +397 -0
- package/examples/launch-example.mjs +589 -0
- package/examples/launch-lifecycle-smoke.mjs +180 -0
- package/examples/launch.mjs +38 -0
- package/examples/quickstart.mjs +37 -0
- package/package.json +8 -3
- package/src/addresses.ts +25 -18
- package/src/client.ts +2 -2
- package/src/launch-api.ts +3 -2
- package/src/lifecycle/abi.ts +107 -12
- package/src/lifecycle/progress.ts +9 -9
- package/src/lifecycle/schema.ts +3 -4
package/docs/launch-lifecycle.md
CHANGED
|
@@ -2,42 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
`@black-market/sdk/lifecycle` is the browser-safe launch API; its exports are also available from `@black-market/sdk`. Supply the exact chain, core, creator and registry domain. Planning, salt preparation, reads and unsigned builders never sign, publish metadata or write to the source chain. A successful controlled-local simulation is not production deployment approval.
|
|
4
4
|
|
|
5
|
-
The canonical authorities are the registry/certification/adapter/config contracts under
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
`
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`
|
|
36
|
-
`
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
`
|
|
40
|
-
|
|
5
|
+
The canonical authorities are the registry/certification/adapter/config contracts under
|
|
6
|
+
`contracts/src/launch/lifecycle/v2`, typed hook deployers, and `contracts/src/launch/fees/v3`
|
|
7
|
+
in the protocol repository. Plan identity is `LaunchPlanV1`. Pool-bound V4 uses **config 5**,
|
|
8
|
+
canonical Abyss uses **config 1**, and generic current shared-V4 support uses **config 4**.
|
|
9
|
+
|
|
10
|
+
## Deployed infrastructure
|
|
11
|
+
|
|
12
|
+
Robinhood mainnet (`4663`) selects the mined `pool-launch-v1` deployment captured at block
|
|
13
|
+
`80548181` in `contracts/deployments/launch/pool-launch-v1/20261005T053747Z-b5a7b88/manifest.json`.
|
|
14
|
+
The manifest records successful receipts and canonical runtime evidence. The graph has two
|
|
15
|
+
adapters and five admitted profiles: one fixed pool-bound V4 profile and four canonical Abyss
|
|
16
|
+
variants. It does not deploy a shared V4 root.
|
|
17
|
+
|
|
18
|
+
| SDK field | Mainnet address |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `launchOrchestrator` | `0xb75CBD17b9aecb7305B4DFcDa69595F783341c0E` |
|
|
21
|
+
| `launchImplementationRegistry` | `0xaa8a410709B79cBA6F118F1be1FF568877A3B8Ee` |
|
|
22
|
+
| `launchFeeOwnerRegistry` | `0x15778Aad08e12D458B2848F035860e2a8c2a0725` |
|
|
23
|
+
|
|
24
|
+
`getAddresses(4663)` exposes this graph; `robinhoodLaunchApplication` exposes the mined
|
|
25
|
+
launch constants. Launch addresses on `31337` and `46631` remain zero unless configured.
|
|
26
|
+
Address overrides are evaluated once on import: bare names win, then `VITE_`, then
|
|
27
|
+
`NEXT_PUBLIC_`. Configure `LAUNCH_ORCHESTRATOR`, `LAUNCH_IMPLEMENTATION_REGISTRY`, and
|
|
28
|
+
`LAUNCH_FEE_OWNER_REGISTRY` from the same deployment evidence.
|
|
29
|
+
|
|
30
|
+
Canonical Abyss defaults are retained. DEX overrides apply on `31337` and `46631`, not
|
|
31
|
+
mainnet. Lending mainnet defaults use `contracts/deployments/robinhood/replacement-infrastructure.json`;
|
|
32
|
+
the workbench's existing lending endpoints follow that replacement. Lending overrides apply
|
|
33
|
+
on `31337` (all three prefixes) and `46631` (`VITE_`/`NEXT_PUBLIC_`); liquidation-executor
|
|
34
|
+
overrides use all three prefixes on every chain. Workbench chain RPC configuration reads
|
|
35
|
+
`VITE_RPC_URL`, then `NEXT_PUBLIC_RPC_URL`, then `RPC_URL`; client factories prefer their explicit
|
|
36
|
+
`rpcUrl`, then `RPC_URL`, then the chain endpoint. Select the chain explicitly in applications.
|
|
37
|
+
|
|
38
|
+
Registry V2 has one `LaunchCertificationV2` child. V4 uses `profileEnvelope`, `profileId`, and
|
|
39
|
+
signed six-argument `registerProfile`. Admin-only `registerAbyssProfile(uint8,registration)`
|
|
40
|
+
independently certifies config-1 variants without an author envelope or royalty allocation.
|
|
41
|
+
The admission EIP-712 domain is `Black Market Launch Registry`, version `2`.
|
|
42
|
+
|
|
43
|
+
`LaunchBoundsV2` has five members: minimum/maximum tick spacing, maximum positions,
|
|
44
|
+
maximum oracle cardinality, and fee-mode flags. Creators select valid LP/hook rates below
|
|
45
|
+
1,000,000 pips, a registered oracle configuration, and per-pool external-liquidity policy.
|
|
46
|
+
Author royalty ceilings are separate. Robinhood P1 `(1,4096)`, P2 `(6,4096)`, and P3 `(17,4096)`
|
|
47
|
+
can use the same admitted profile; the selected oracle is checked at the pinned block.
|
|
48
|
+
With `externalLiquidityDisabled=false`, third-party LP add/remove is allowed after opening.
|
|
49
|
+
Permanent launch custody and pre-opening protection still apply.
|
|
50
|
+
|
|
51
|
+
The deployed pool stack uses `FixedFeePoolHookV1`, `PoolHookDeployerV1`,
|
|
52
|
+
`PoolMarketAdapterV1`, and `PoolFeeCollectorFactoryV1`. The complete `fixedFeePoolHookV1Abi`
|
|
53
|
+
includes the exact **one-tuple, 18-field constructor**, callbacks, events, and errors from the
|
|
54
|
+
mined artifact. Its fixed scalar fee calculation does not imply a scalar-argument constructor.
|
|
55
|
+
Generic shared contracts are `FixedFeeSharedHookV1`, `SharedHookDeployerV1`, and
|
|
56
|
+
`SharedMarketAdapterV1`; they require their own admitted deployment graph.
|
|
57
|
+
Other current ABI exports include `sharedMarketAdapterV1Abi`, `sharedHookDeployerV1Abi`,
|
|
58
|
+
`poolMarketAdapterV1Abi`, `poolHookDeployerV1Abi`, and `poolFeeCollectorFactoryV1Abi`.
|
|
59
|
+
Validation uses `validateV4LifecycleMarket`; the collector factory getter is
|
|
60
|
+
`dependencyDigest(address)`. Identity domains are `black-market.launch-profile.v2`,
|
|
61
|
+
`black-market.v4-dependencies.v2`, and `black-market.pool-bound-market-economics.v1`.
|
|
41
62
|
|
|
42
63
|
## Public operations
|
|
43
64
|
|
|
@@ -108,13 +129,13 @@ Registry `authorizationDigest`, `beneficiaryNonces` and `registerProfile` ABIs e
|
|
|
108
129
|
(uint16,uint24,int24,uint160,uint24,uint8,uint8,address,bool,bytes32,bytes32,bytes32,bytes32,address,uint16,(int24,int24,uint128,bytes32,uint256)[])
|
|
109
130
|
```
|
|
110
131
|
|
|
111
|
-
Both preserve LP/hook fees, tick spacing, opening price, fee mode/denominator/treasury, external-liquidity policy and canonical oracle identity. Then come `profileId`, `termsDigest`, `developerBeneficiary
|
|
132
|
+
Both preserve LP/hook fees, tick spacing, opening price, fee mode/denominator/treasury, external-liquidity policy, and canonical oracle identity. Then come `profileId`, `termsDigest`, `developerBeneficiary`, and explicit `developerFeeBps`, followed by positions. Version 5 inserts `hookSalt` immediately before `profileId`. Every developer rate, including zero, is creator-selected. Copy terms from the selected profile's envelope. Inner/outer profile IDs must match; author identity is not the live payout. The creator rate cannot exceed either reviewed maximum or protocol ceiling.
|
|
112
133
|
|
|
113
134
|
```ts
|
|
114
135
|
const profile = profiles.find((row) => row.id === selectedProfileId);
|
|
115
136
|
if (!profile?.admitted || !profile.envelope || !profile.developerTerms) throw new Error("Selected profile is not reviewed/admitted");
|
|
116
|
-
const config =
|
|
117
|
-
version:
|
|
137
|
+
const config = encodePoolBoundV4LifecycleMarketConfig({
|
|
138
|
+
version: 5, hookSalt: zeroHash, lpFeePips, tickSpacing, sqrtPriceX96, hookFeePips, feeMode,
|
|
118
139
|
protocolFeeDenominator: profile.envelope.protocolFeeDenominator,
|
|
119
140
|
treasury: profile.envelope.protocolTreasury,
|
|
120
141
|
externalLiquidityDisabled: creatorSelectedExternalLiquidityDisabled,
|
|
@@ -238,6 +259,143 @@ Lifecycle dividend tokens retain independent current-owner dividend bounty up to
|
|
|
238
259
|
node examples/generate-lifecycle-commitment-fixture.mjs test/fixtures/launch-lifecycle-v1.json
|
|
239
260
|
```
|
|
240
261
|
|
|
241
|
-
|
|
262
|
+
Build and run the offline unit suite with `pnpm test`, and deployed read-only discovery with
|
|
263
|
+
`pnpm examples`. Unit regressions cover commitment/identity/numerical domains,
|
|
264
|
+
reviewed terms/rate/bounds, salt normalization/mining, receipt recovery, and author
|
|
265
|
+
authentication/routing/page outcomes. Wire vectors remain
|
|
266
|
+
offline schema references; they are not a mainnet launch or an admitted deployment graph.
|
|
267
|
+
|
|
268
|
+
`examples/launch.mjs` reviews a saved plan without signatures or source-chain writes:
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
pnpm build
|
|
272
|
+
node examples/launch.mjs --plan plan.json --rpc https://rpc.mainnet.chain.robinhood.com/ --mode staged --mine
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The saved plan must use that RPC's chain and current deployment. `--mine` finalizes bound
|
|
276
|
+
salts offchain; `--limits current-limits.json`, `--receipts receipts.json`, and `--confirmations N`
|
|
277
|
+
supply explicit execution/recovery evidence. The command never invents provider/account limits.
|
|
278
|
+
Without a sequential simulation backend and matching execution-limit provenance, its review
|
|
279
|
+
can be provisional and cannot produce an admitted next transaction.
|
|
280
|
+
|
|
281
|
+
`examples/launch-lifecycle-smoke.mjs manifest.json sdk-plans.json` executes Solidity-exported
|
|
282
|
+
plans only on explicitly authorized owned loopback fixtures. It exercises atomic/staged
|
|
283
|
+
modes, typed predeployment, ordered buys, permanent custody, canonical recovery, no-argument
|
|
284
|
+
V3 harvest, and authenticated author claims. `test/lifecycle-chain.test.mjs` exercises
|
|
285
|
+
real-graph refusals/reorg/cancellation with the same fixture environment. See
|
|
286
|
+
[example instructions](../examples/README.md#actual-owned-fixture-proof) for the explicit
|
|
287
|
+
local-execution opt-in and required files.
|
|
288
|
+
|
|
289
|
+
## Individual token creation examples
|
|
290
|
+
|
|
291
|
+
Eight independent `examples/launch-erc20-*.mjs` / `launch-erc404-*.mjs` files invoke
|
|
292
|
+
the shared `runLaunchExample(caseObject)` using fixed economics and no parameters or
|
|
293
|
+
fixture files. See the [example guide](../examples/README.md#individual-token-creation)
|
|
294
|
+
for the eight one-line commands and setup-once working-directory `.env`.
|
|
295
|
+
Node 24+ loads `.env` once, with existing process environment taking precedence.
|
|
296
|
+
`PRIVATE_KEY` and `LAUNCH_API_URL` are required before RPC/signing/API work; there is
|
|
297
|
+
no default key, guessed API or API-omission mode. Running a case deliberately authorizes
|
|
298
|
+
real local signing, source-chain transactions and API publication; mainnet writes are
|
|
299
|
+
irreversible. The official SDK chain-4663 RPC is the default.
|
|
300
|
+
|
|
301
|
+
The implementation imports public `@black-market/sdk`, resolves `getAddresses(4663)`,
|
|
302
|
+
derives the creator from the key and discovers the actual admitted profiles. V4 requires
|
|
303
|
+
bound topology/config `5`; Abyss requires exact adapter `profileId(3)` QUOTE_ORACLE/config
|
|
304
|
+
`1`. It verifies wrapped-native binding/decimals and registered P1 oracle `(1,4096)`.
|
|
305
|
+
All eight original token/reward/venue/position/mode cases retain their exact economics:
|
|
306
|
+
ERC20 `1_000_000e18` supply; ERC404 `10_000e18` supply / `100e18` NFT unit; selected
|
|
307
|
+
staking/dividends and token-only burn; one through five permanent positions and ordered
|
|
308
|
+
native-wrap opening buys. It saves identity/finalized salts/plans before execution and
|
|
309
|
+
never changes mode, drops positions/buys or overrides failed admission.
|
|
310
|
+
Optional `NFT_BASE_URI` provides an ERC404 base URI you actually host; its default is
|
|
311
|
+
empty, with real NFT units/mirror behavior but no claim of hosted NFT metadata.
|
|
312
|
+
|
|
313
|
+
Optional `SIMULATION_RPC_URL` uses the canonical SDK controlled fork on a separate
|
|
314
|
+
owned disposable loopback Anvil. Otherwise real native sequential `eth_simulateV1` is
|
|
315
|
+
required. Only the simulation fork is reset/impersonated/reverted. Source RPC requests
|
|
316
|
+
have a 120-second bound and are not retried. Default gas `16000000`, calldata `131072`
|
|
317
|
+
and headroom `1000` bps are explicitly **EXAMPLE ceilings, not verified provider/account
|
|
318
|
+
limits**; the chain cap is bounded by observed block gas limits. Environment overrides
|
|
319
|
+
are documented in the example guide and remain subject to full SDK admission.
|
|
320
|
+
|
|
321
|
+
Execution rechecks chain/creator/destination and exact finalized calldata before each
|
|
322
|
+
send. Exact admitted envelopes are signed locally; computed hashes and unsigned
|
|
323
|
+
envelopes are saved **before** the single raw broadcast, and included receipts are
|
|
324
|
+
saved before status/provenance assertions. One canonical confirmation is required.
|
|
325
|
+
Actual verification covers Active state, factory/token runtime/name/symbol/kind/rewards,
|
|
326
|
+
ERC404 unit/URI/mirror, opened markets, sealed V4 custody/permanent Abyss lock terms,
|
|
327
|
+
fee policies and ordered activation buys.
|
|
328
|
+
|
|
329
|
+
Actual SDK API metadata staging uses locally signed full-domain attribution. Only the
|
|
330
|
+
real activation hash is published. Genuine pending-indexer HTTP `202` is polled within
|
|
331
|
+
90 seconds respecting `Retry-After`; other failures are not retried. Success requires
|
|
332
|
+
an optimistic/final session and real indexed `/api/v1/launches/<token>?chainId=4663`
|
|
333
|
+
DTO with matching creator/token/hash/metadata. Missing/incompatible indexing fails
|
|
334
|
+
honestly without manufacturing projections, skipping API or launching another token.
|
|
335
|
+
|
|
336
|
+
Every run automatically creates fresh `launch-results/<timestamp-case-random>/`:
|
|
337
|
+
|
|
338
|
+
| Artifact | Evidence |
|
|
339
|
+
| --- | --- |
|
|
340
|
+
| `events.jsonl` | Timestamped case/stage events, RPC/API errors, admission/simulation and actual chain observations. |
|
|
341
|
+
| `plan.json` | Full finalized portable SDK plan saved before execution. |
|
|
342
|
+
| `receipts.json` | Exact signed-envelope hashes retained pre-broadcast, followed by real receipts/references. |
|
|
343
|
+
| `result.json` | `black-market.launch-example-result.v1`, end-to-end status, failure stage and causal evidence. |
|
|
344
|
+
| `published-token.json` | Actual indexed API representation. |
|
|
345
|
+
| `private-recovery.json` | Mode `0600`; signed raw bytes, API signature and one-time capability. Never share/commit. |
|
|
346
|
+
|
|
347
|
+
Public artifacts redact known keys/signatures/raw bytes/capabilities/auth values and
|
|
348
|
+
endpoint secrets while retaining public calldata/hashes/revert bytes. Configuration,
|
|
349
|
+
admission, broadcast, publication and interruption failures exit nonzero and preserve
|
|
350
|
+
evidence. No source rollback, cancellation, broadcast retry or relaunch occurs.
|
|
351
|
+
Inspect retained transaction hashes before deciding to run a new case after an
|
|
352
|
+
ambiguous send. `test/launch-example.test.mjs` covers offline signing/retention/config
|
|
353
|
+
boundaries only, not actual chain/API proof. The older independent whole-graph local
|
|
354
|
+
Solidity-exported proof remains separate.
|
|
355
|
+
|
|
356
|
+
## Real HTTP API integration
|
|
357
|
+
|
|
358
|
+
The opt-in suites use `LaunchApiClient` and actual HTTP requests—not a mocked transport.
|
|
359
|
+
They do not start a service or provision storage. Configure an abyss-api service with:
|
|
360
|
+
|
|
361
|
+
- `/api/v1/launch-upload-sessions` and its capability-protected read route;
|
|
362
|
+
- real application PostgreSQL storage with launch-upload-session migrations applied;
|
|
363
|
+
- an enabled request chain matching `LAUNCH_API_TEST_CHAIN_ID`;
|
|
364
|
+
- its current launch verifying contract matching `LAUNCH_API_TEST_ORCHESTRATOR`.
|
|
365
|
+
|
|
366
|
+
For the actual abyss-api service, that verifying contract is the configured deployment
|
|
367
|
+
`contracts.launchFactory` field, which must contain the current orchestrator address.
|
|
368
|
+
The signed attribution domain is `Abyss Launch Attribution`, version `1`. Session signature
|
|
369
|
+
deadlines must be future timestamps at most 15 minutes away. Metadata hashes use canonical
|
|
370
|
+
NFC/trimmed text, normalized URLs, fixed field order, and null absent optional values.
|
|
371
|
+
|
|
372
|
+
| Environment | Meaning |
|
|
373
|
+
| --- | --- |
|
|
374
|
+
| `LAUNCH_API_TEST_URL` | Required HTTP service root, e.g. `http://127.0.0.1:18763`; no implicit production target. |
|
|
375
|
+
| `LAUNCH_API_TEST_CHAIN_ID` | Defaults to `4663`; must be configured on the test service. |
|
|
376
|
+
| `LAUNCH_API_TEST_ORCHESTRATOR` | Defaults to `0xb75CBD17b9aecb7305B4DFcDa69595F783341c0E`; must match the service's signing domain. |
|
|
377
|
+
| `LAUNCH_API_TEST_PRIVATE_KEY` | Required only for the explicit signed suite; disposable EOA key, never a production key. |
|
|
378
|
+
|
|
379
|
+
```sh
|
|
380
|
+
# Read-only capability/error boundaries; no key and no storage writes.
|
|
381
|
+
LAUNCH_API_TEST_URL=http://127.0.0.1:18763 pnpm test:api
|
|
382
|
+
|
|
383
|
+
# Signed metadata-session writes, allowed only on an owned disposable loopback service.
|
|
384
|
+
LAUNCH_API_TEST_URL=http://127.0.0.1:18763 \
|
|
385
|
+
LAUNCH_API_TEST_PRIVATE_KEY="$DISPOSABLE_TEST_PRIVATE_KEY" pnpm test:api:write
|
|
386
|
+
```
|
|
242
387
|
|
|
243
|
-
|
|
388
|
+
The write suite creates metadata-only sessions, reads persisted normalized metadata,
|
|
389
|
+
replays the byte-identical signed body without reissuing the one-time capability, refuses a
|
|
390
|
+
changed authorized payload under the same idempotency key, and checks capability isolation.
|
|
391
|
+
It also rejects wrong signers, wrong orchestrator/chain domains, altered metadata, a changed
|
|
392
|
+
idempotency key, expired authorization, and invalid signatures. The private key signs EIP-712
|
|
393
|
+
metadata only; it need not have a balance. Unique session/key/nonces permit repeat runs.
|
|
394
|
+
The disposable service operator owns database cleanup; the API has no session-deletion route.
|
|
395
|
+
|
|
396
|
+
Neither suite needs an image store, indexed launch, confirmed transaction hash, or chain
|
|
397
|
+
write. Metadata sessions do not prove token deployment, image publication, or transaction
|
|
398
|
+
indexing. Image/upload/publication operations require those additional real prerequisites
|
|
399
|
+
and are not exercised here. Explicitly selected suites fail on missing URL/key, absent
|
|
400
|
+
storage/routes, an unreachable service, or incompatible signing configuration instead of
|
|
401
|
+
silently skipping. Ordinary `pnpm test` stays offline and does not select HTTP integration.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copy to .env in the directory from which you run node (Node 24+).
|
|
2
|
+
# Running a launch-*.mjs file deliberately signs, spends funds and publishes.
|
|
3
|
+
PRIVATE_KEY=
|
|
4
|
+
LAUNCH_API_URL=
|
|
5
|
+
|
|
6
|
+
# Optional: blank uses the SDK official Robinhood chain-4663 mainnet RPC.
|
|
7
|
+
RPC_URL=
|
|
8
|
+
# Optional: separate owned loopback Anvil used only for SDK controlled simulation.
|
|
9
|
+
# Blank selects the actual RPC native eth_simulateV1 backend.
|
|
10
|
+
SIMULATION_RPC_URL=
|
|
11
|
+
# Optional ERC404 NFT metadata base URI that you actually host; blank means empty URI.
|
|
12
|
+
NFT_BASE_URI=
|
|
13
|
+
|
|
14
|
+
# Optional EXAMPLE ceilings, NOT verified provider/account limits.
|
|
15
|
+
# Chain cap is also bounded by every observed block gas limit.
|
|
16
|
+
# EXAMPLE_CHAIN_GAS_CAP=16000000
|
|
17
|
+
# EXAMPLE_RPC_GAS_CAP=16000000
|
|
18
|
+
# EXAMPLE_ACCOUNT_GAS_CAP=16000000
|
|
19
|
+
# EXAMPLE_MAX_CALLDATA_BYTES=131072
|
|
20
|
+
# EXAMPLE_HEADROOM_BPS=1000
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
The launch examples use the installed public `@black-market/sdk` package and viem,
|
|
4
|
+
including when copied into a consumer project. The deployed chain-4663 graph uses
|
|
5
|
+
pool-bound V4 config 5 and canonical Abyss config 1. Discovery is read-only; running
|
|
6
|
+
a fixed launch example with configured wallet/API deliberately executes real writes.
|
|
7
|
+
|
|
8
|
+
| Script | Behavior |
|
|
9
|
+
| --- | --- |
|
|
10
|
+
| `quickstart.mjs` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
|
|
11
|
+
| `launch.mjs` | Reviews/reconstructs an explicit saved plan and selected atomic/staged mode; optional offchain config-5 salt mining. Prints simulation, progress, and an admitted unsigned next transaction when evidence permits. |
|
|
12
|
+
| `generate-lifecycle-commitment-fixture.mjs` | Independent offline ABI reference for current config-4/Abyss commitment bytes/hash/identity, not a deployment or executable launch. |
|
|
13
|
+
| `launch-lifecycle-smoke.mjs` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
|
|
14
|
+
| `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. |
|
|
15
|
+
|
|
16
|
+
## Deployed read-only discovery
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
pnpm install
|
|
20
|
+
pnpm examples
|
|
21
|
+
# Optional: RPC_URL=https://your-robinhood-rpc pnpm examples
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`CHAIN_ID` defaults to `4663`. Local `31337` and workbench `46631` require a matching
|
|
25
|
+
RPC and explicit `LAUNCH_ORCHESTRATOR`, `LAUNCH_IMPLEMENTATION_REGISTRY`, and
|
|
26
|
+
`LAUNCH_FEE_OWNER_REGISTRY`. The example checks RPC chain identity and registry binding.
|
|
27
|
+
Profile discovery verifies live registry admission and certified dependencies; it does
|
|
28
|
+
not build/sign a launch, choose a developer fee, or select market economics.
|
|
29
|
+
|
|
30
|
+
## Unsigned saved-plan review
|
|
31
|
+
|
|
32
|
+
Supply full `LaunchPlanV1` JSON using the selected RPC's current deployment:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pnpm build
|
|
36
|
+
node examples/launch.mjs \
|
|
37
|
+
--plan plan.json --rpc https://rpc.mainnet.chain.robinhood.com/ --mode staged --mine
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`--mine` finalizes config-5 salts offchain and prints the final plan. Persist that exact
|
|
41
|
+
commitment before begin. `--receipts receipts.json` and `--confirmations N` restore
|
|
42
|
+
canonical recovery context. The CLI never signs, submits source-chain transactions,
|
|
43
|
+
uploads metadata, or publishes a launch. Modes never fall back silently.
|
|
44
|
+
|
|
45
|
+
Executable admission additionally requires current matching execution-limit evidence
|
|
46
|
+
(`--limits current-limits.json`) and sequential `eth_simulateV1`, or an explicitly
|
|
47
|
+
supplied **separate disposable loopback fork** (`--fork-rpc URL`). Limits must include
|
|
48
|
+
chain/account/core/observed-block/hash provenance and actual chain/RPC/account/calldata
|
|
49
|
+
caps; encode bigint values as decimal strings. Missing facts produce provisional/refused
|
|
50
|
+
admission, not invented provider/account policy. See the
|
|
51
|
+
[lifecycle guide](../docs/launch-lifecycle.md#execution-constraints-and-stateful-simulation).
|
|
52
|
+
|
|
53
|
+
## Real HTTP metadata sessions
|
|
54
|
+
|
|
55
|
+
The real HTTP integration suite uses the public `LaunchApiClient` against a separately
|
|
56
|
+
running service. Reads are unsigned; metadata-session writes require a disposable key
|
|
57
|
+
and an owned loopback service with real application storage:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
LAUNCH_API_TEST_URL=http://127.0.0.1:18763 pnpm test:api
|
|
61
|
+
LAUNCH_API_TEST_URL=http://127.0.0.1:18763 \
|
|
62
|
+
LAUNCH_API_TEST_PRIVATE_KEY="$DISPOSABLE_TEST_PRIVATE_KEY" pnpm test:api:write
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
These are metadata-only session tests, not token deployment or image/transaction
|
|
66
|
+
publication. No image store, indexer, wallet balance, or chain transaction is needed.
|
|
67
|
+
See [service prerequisites](../docs/launch-lifecycle.md#real-http-api-integration).
|
|
68
|
+
|
|
69
|
+
## Individual token creation
|
|
70
|
+
|
|
71
|
+
**Running one of these files signs and broadcasts a real launch and writes to your
|
|
72
|
+
configured API. Mainnet execution is irreversible and spends real funds.** Choose
|
|
73
|
+
one command per intended launch; there are no flags, parameters or fixture files.
|
|
74
|
+
|
|
75
|
+
### Setup once
|
|
76
|
+
|
|
77
|
+
Use **Node 24+**. In this repository run `pnpm install`. In a consumer project install
|
|
78
|
+
both public dependencies with `pnpm add @black-market/sdk viem` (or
|
|
79
|
+
`npm install @black-market/sdk viem`) and copy the selected files with
|
|
80
|
+
`launch-example.mjs` and `launch-example-support.mjs` into `examples/`.
|
|
81
|
+
Copy `examples/.env.example` to `.env` in the directory you will run commands from:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
cp examples/.env.example .env
|
|
85
|
+
chmod 600 .env
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Edit `.env` once:
|
|
89
|
+
|
|
90
|
+
```dotenv
|
|
91
|
+
PRIVATE_KEY=
|
|
92
|
+
LAUNCH_API_URL=
|
|
93
|
+
RPC_URL=
|
|
94
|
+
SIMULATION_RPC_URL=
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Set `PRIVATE_KEY` to **your funded EOA's** 32-byte hex key and `LAUNCH_API_URL` to
|
|
98
|
+
your actual HTTPS or owned loopback API service root. There is no default wallet,
|
|
99
|
+
public development key, guessed API URL, or silent API skip. The API needs actual
|
|
100
|
+
application storage and an indexer observing the same chain as the execution RPC.
|
|
101
|
+
Existing environment variables take precedence over the working-directory `.env`,
|
|
102
|
+
loaded once using Node's native `process.loadEnvFile`. No shell interpolation is used.
|
|
103
|
+
|
|
104
|
+
Blank `RPC_URL` uses the SDK official Robinhood chain-4663 mainnet endpoint; HTTPS
|
|
105
|
+
providers and explicit owned loopback HTTP execution RPCs are supported.
|
|
106
|
+
The creator is derived locally from the key, and the deployment/WETH addresses come
|
|
107
|
+
from `getAddresses(4663)`. The runner checks chain identity, EOA and deployed core,
|
|
108
|
+
discovers admitted profiles, verifies the actual wrapped-native binding and reads
|
|
109
|
+
the registered P1 `(1,4096)` oracle configuration. No fixture defines these facts.
|
|
110
|
+
Optional `NFT_BASE_URI` supplies your actually hosted ERC404 NFT metadata base URI.
|
|
111
|
+
Blank uses an empty base URI: NFT units/mirror behavior remain real, but the example
|
|
112
|
+
does not claim hosted NFT metadata exists.
|
|
113
|
+
|
|
114
|
+
Blank `SIMULATION_RPC_URL` selects the actual SDK native sequential `eth_simulateV1`
|
|
115
|
+
backend. Set it only to a **separate owned disposable loopback Anvil** for the canonical
|
|
116
|
+
SDK controlled fork; only this simulation environment is reset/impersonated/reverted.
|
|
117
|
+
Unsupported native simulation, insufficient funds or failed admission stop before API
|
|
118
|
+
staging/broadcast. There is no mode fallback, admission override or reduced case.
|
|
119
|
+
|
|
120
|
+
### Commands and fixed cases
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
node examples/launch-erc20-v4.mjs
|
|
124
|
+
node examples/launch-erc20-abyss.mjs
|
|
125
|
+
node examples/launch-erc404-v4.mjs
|
|
126
|
+
node examples/launch-erc404-abyss.mjs
|
|
127
|
+
node examples/launch-erc20-staking-v4.mjs
|
|
128
|
+
node examples/launch-erc20-dividends-abyss.mjs
|
|
129
|
+
node examples/launch-erc20-burn-mixed.mjs
|
|
130
|
+
node examples/launch-erc404-dividends-mixed.mjs
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| File suffix | Token / rewards | Markets and permanent positions | Mode / opening buys |
|
|
134
|
+
| --- | --- | --- | --- |
|
|
135
|
+
| `erc20-v4` | ERC20 / none | V4: 1 | atomic / 1 |
|
|
136
|
+
| `erc20-abyss` | ERC20 / none | Abyss: 1 | atomic / 1 |
|
|
137
|
+
| `erc404-v4` | ERC404 / none | V4: 1 | staged / 1 |
|
|
138
|
+
| `erc404-abyss` | ERC404 / none | Abyss: 1 | atomic / 1 |
|
|
139
|
+
| `erc20-staking-v4` | ERC20 / staking | V4: 2 | staged / 2 |
|
|
140
|
+
| `erc20-dividends-abyss` | ERC20 / dividends | Abyss: 3 | staged / 1 |
|
|
141
|
+
| `erc20-burn-mixed` | ERC20 / token-only burn 3000 bps | dual-fee V4: 2; Abyss: 1 | staged / 1 per market |
|
|
142
|
+
| `erc404-dividends-mixed` | ERC404 / dividends | V4: 2; Abyss: 3 | staged / 1 per market |
|
|
143
|
+
|
|
144
|
+
ERC20 supply is `1_000_000e18`; ERC404 supply is `10_000e18`, NFT unit `100e18`.
|
|
145
|
+
Positions retain `1000e18` liquidity and the case's exact ranges. Each ordered buy
|
|
146
|
+
spends up to `0.001 ETH` through native-wrap funding. Rewards use 4000 bps where
|
|
147
|
+
selected; token-only burn is 3000 bps in the burn case. V4 uses frozen registered
|
|
148
|
+
treasury/author terms with developer rate `0`; executor fee is 275 bps.
|
|
149
|
+
Hook salts/random identities are finalized and saved before execution.
|
|
150
|
+
|
|
151
|
+
### Example execution ceilings
|
|
152
|
+
|
|
153
|
+
Defaults are **EXAMPLE ceilings, not verified provider or account limits**:
|
|
154
|
+
chain/RPC/account gas `16000000`, calldata `131072` bytes, headroom `1000` bps.
|
|
155
|
+
The chain cap is additionally bounded by every observed block gas limit. If your
|
|
156
|
+
provider/account policy differs, configure decimal environment values:
|
|
157
|
+
`EXAMPLE_CHAIN_GAS_CAP`, `EXAMPLE_RPC_GAS_CAP`, `EXAMPLE_ACCOUNT_GAS_CAP`,
|
|
158
|
+
`EXAMPLE_MAX_CALLDATA_BYTES`, `EXAMPLE_HEADROOM_BPS`. These do not bypass SDK admission.
|
|
159
|
+
|
|
160
|
+
### Evidence and failure recovery
|
|
161
|
+
|
|
162
|
+
Each run automatically creates `launch-results/<timestamp-case-random>/`; there is
|
|
163
|
+
no user output option. Inspect `result.json`, `events.jsonl`, finalized `plan.json`,
|
|
164
|
+
`receipts.json` and `published-token.json`. Exact admitted wallet envelopes are signed
|
|
165
|
+
locally; computed hashes and unsigned envelopes are durably retained as
|
|
166
|
+
`broadcast-attempt` **before the one raw broadcast**. Real receipts are saved before
|
|
167
|
+
status/canonical-state assertions. No unlocked-account signing or sending is used.
|
|
168
|
+
Public evidence redacts known keys, signatures, signed raw bytes, API capabilities,
|
|
169
|
+
authorization values and RPC endpoint credentials. Only `private-recovery.json`
|
|
170
|
+
(mode `0600`) retains raw signed transactions and one-time API recovery material;
|
|
171
|
+
never share or commit it. `launch-results/` is ignored.
|
|
172
|
+
|
|
173
|
+
Every case requires actual API metadata staging, publication using the activation
|
|
174
|
+
hash, and an indexed DTO matching token/creator/hash/metadata. Genuine pending-indexer
|
|
175
|
+
HTTP `202` responses are polled for up to 90 seconds respecting `Retry-After`;
|
|
176
|
+
other API failures are not retried or converted to partial success. Broadcast/API
|
|
177
|
+
failures retain logs/hashes and exit nonzero. The runner never retries a raw send,
|
|
178
|
+
relaunches, cancels or rolls back the source chain. **Do not blindly rerun after an
|
|
179
|
+
ambiguous broadcast**: inspect the durable transaction hash on chain first.
|
|
180
|
+
See [chain/API invariants](../docs/launch-lifecycle.md#individual-token-creation-examples).
|
|
181
|
+
|
|
182
|
+
### Owned-local wallet verification helpers
|
|
183
|
+
|
|
184
|
+
`launch-example-support.mjs` exports
|
|
185
|
+
`createLocalLaunchWallet({privateKey,creator,chainId,orchestrator,client,redactor})`
|
|
186
|
+
and `submitSignedRecorded({transaction,wallet,client,wait,artifacts,signal})`.
|
|
187
|
+
`client.request({method,params})` is an explicit RPC adapter; `transaction` carries
|
|
188
|
+
`id`, `kind`, and exact unsigned `wire` chain/from/to/data/value/gas fields plus
|
|
189
|
+
optional nonce/fees/type/accessList. `wait(hash)` returns a real receipt.
|
|
190
|
+
The signer exposes `address`, `signTypedData(typedData)` and `signTransaction(wire)`
|
|
191
|
+
returning `{wire,rawTransaction,transactionHash}`. Retain the result privately.
|
|
192
|
+
Use `RunArtifacts(output,caseId,redactor)` with `Redactor` and a fresh directory for
|
|
193
|
+
durable evidence; call `initialize()` before work and `finish(status,error)` afterward.
|
|
194
|
+
The shared `runLaunchExample(caseObject)` in `launch-example.mjs` takes the same fixed
|
|
195
|
+
case objects as the eight files, loads environment and auto-creates its output.
|
|
196
|
+
Offline diagnostic tests are in `test/launch-example.test.mjs`; they do not claim
|
|
197
|
+
real launch or API-indexer proof.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
## Actual owned-fixture proof
|
|
201
|
+
|
|
202
|
+
The manifest must declare `fixtureOnly: true`, exact reviewed graph addresses, and
|
|
203
|
+
`executionLimits.provenance.scope: "controlled-local-measurement"`. The plan file
|
|
204
|
+
contains Solidity-exported `plans` with encoded-plan/hash/identity/token vectors.
|
|
205
|
+
Do not pass a mined mainnet manifest as a writable fixture.
|
|
206
|
+
|
|
207
|
+
```sh
|
|
208
|
+
pnpm build
|
|
209
|
+
LAUNCH_LIFECYCLE_RPC_URL=http://127.0.0.1:18555 \
|
|
210
|
+
LAUNCH_LIFECYCLE_FORK_RPC_URL=http://127.0.0.1:18556 \
|
|
211
|
+
LAUNCH_LIFECYCLE_ALLOW_LOCAL_EXECUTION=1 \
|
|
212
|
+
node examples/launch-lifecycle-smoke.mjs manifest.json sdk-plans.json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
This explicitly authorized command executes disposable fixture transactions and
|
|
216
|
+
restores snapshots per plan/mode. It exercises ordered buys, canonical Active state,
|
|
217
|
+
permanent custody, typed deployment provenance, V3 no-argument `claimAndSplit()`,
|
|
218
|
+
reserved owner/developer balances, and authenticated author claims. Cursor completion
|
|
219
|
+
and payment success stay separate.
|
|
220
|
+
|
|
221
|
+
For chain boundary regressions, also set `LAUNCH_LIFECYCLE_MANIFEST` and
|
|
222
|
+
`LAUNCH_LIFECYCLE_FIXTURES`, then run `node --test test/lifecycle-chain.test.mjs` with
|
|
223
|
+
the same local-execution environment. Ordinary `pnpm test` does not authorize chain writes.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { encodeAbiParameters, keccak256, parseAbiParameters, stringToHex } from "viem";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
// Independent wire-format reference: does not import the SDK encoder under test.
|
|
5
|
+
const wire = "(uint256 chainId,address orchestrator,address creator,uint256 nonce,(uint8 kind,uint8 rewardMode,string name,string symbol,uint256 supply,uint256 nftUnit,string metadataURI,bytes32 salt,address inventoryRecipient,bool burnOnCancel) token,(address asset,uint256 amount,uint8 kind,address inputAsset,uint256 inputAmount,address target,bytes data)[] funding,(address asset,uint16 ownerBps,uint16 rewardsBps,uint16 burnBps)[] feeAssets,(bytes32 adapterId,bytes32 profileId,address quoteAsset,uint256 tokenBudget,uint32 configVersion,bytes config)[] markets,(uint32 marketIndex,uint256 quoteAmountIn,uint256 minTokenOut,address recipient,uint160 sqrtPriceLimitX96)[] buys,uint256 deadline,uint16 executorFeeBps) plan";
|
|
6
|
+
const address = (value) => `0x${value.toString(16).padStart(40, "0")}`;
|
|
7
|
+
const bytes32 = (value) => `0x${value.toString(16).padStart(64, "0")}`;
|
|
8
|
+
const zero = address(0);
|
|
9
|
+
const plan = {
|
|
10
|
+
chainId: 31337n, orchestrator: address(0xf0), creator: address(0xa0), nonce: 2n ** 192n + 17n,
|
|
11
|
+
token: { kind: 1, rewardMode: 1, name: "Lifecycle commitment 🜁", symbol: "LCV", supply: 10n ** 27n,
|
|
12
|
+
nftUnit: 100n * 10n ** 18n, metadataURI: "ipfs://lifecycle-vector/", salt: bytes32(0x1234), inventoryRecipient: address(0xa0), burnOnCancel: true },
|
|
13
|
+
funding: [
|
|
14
|
+
{ asset: address(0x20), amount: 500_000_001n, kind: 0, inputAsset: address(0x20), inputAmount: 500_000_001n, target: zero, data: "0x" },
|
|
15
|
+
{ asset: address(0x30), amount: 10n ** 20n, kind: 1, inputAsset: address(0x30), inputAmount: 10n ** 20n, target: zero, data: "0x" },
|
|
16
|
+
],
|
|
17
|
+
feeAssets: [
|
|
18
|
+
{ asset: address(0x10), ownerBps: 8000, rewardsBps: 0, burnBps: 2000 },
|
|
19
|
+
{ asset: address(0x20), ownerBps: 6000, rewardsBps: 4000, burnBps: 0 },
|
|
20
|
+
{ asset: address(0x30), ownerBps: 6000, rewardsBps: 4000, burnBps: 0 },
|
|
21
|
+
],
|
|
22
|
+
markets: [
|
|
23
|
+
{ adapterId: bytes32(1), profileId: bytes32(11), quoteAsset: address(0x20), tokenBudget: 4n * 10n ** 26n, configVersion: 4,
|
|
24
|
+
config: encodeAbiParameters(parseAbiParameters("(uint16,uint24,int24,uint160,uint24,uint8,uint8,address,bool,bytes32,bytes32,bytes32,address,uint16,(int24,int24,uint128,bytes32,uint256)[])"), [[4, 3000, 60, 2n ** 96n, 10000, 0, 6, address(0xa0), true, keccak256(encodeAbiParameters(parseAbiParameters("uint24,uint16"), [17, 4096])), bytes32(11), bytes32(21), address(0xd0), 250, [[60, 120, 10n ** 18n, bytes32(1), 10n ** 24n]]]]) },
|
|
25
|
+
{ adapterId: bytes32(2), profileId: bytes32(12), quoteAsset: address(0x30), tokenBudget: 5n * 10n ** 26n, configVersion: 1,
|
|
26
|
+
config: encodeAbiParameters(parseAbiParameters("(uint8,uint24,bytes32,uint160,(int24,int24,uint128,uint256)[])"), [[3, 3000, bytes32(0x55), 2n ** 96n, [[60, 120, 10n ** 18n, 10n ** 24n]]]]) },
|
|
27
|
+
],
|
|
28
|
+
buys: [
|
|
29
|
+
{ marketIndex: 1, quoteAmountIn: 13n * 10n ** 18n, minTokenOut: 1n, recipient: address(0xb1), sqrtPriceLimitX96: 2n ** 96n - 1n },
|
|
30
|
+
{ marketIndex: 0, quoteAmountIn: 20_000_000n, minTokenOut: 2n, recipient: address(0xb2), sqrtPriceLimitX96: 2n ** 96n - 1n },
|
|
31
|
+
{ marketIndex: 1, quoteAmountIn: 7n * 10n ** 18n, minTokenOut: 3n, recipient: address(0xb3), sqrtPriceLimitX96: 2n ** 96n - 1n },
|
|
32
|
+
],
|
|
33
|
+
deadline: 2_000_000_000n, executorFeeBps: 275,
|
|
34
|
+
};
|
|
35
|
+
const domain = keccak256(stringToHex("BLACK_MARKET_LAUNCH_PLAN_V1"));
|
|
36
|
+
const fixture = {
|
|
37
|
+
schema: "black-market.launch-lifecycle-commitment-vector.v1", description: "Portable reviewed config-4/Abyss economic wire vector, not a deployed launch. Both modes commit identical economics.",
|
|
38
|
+
plan, encodedPlan: encodeAbiParameters(parseAbiParameters(wire), [plan]),
|
|
39
|
+
planHash: keccak256(encodeAbiParameters(parseAbiParameters(`bytes32 domain,${wire}`), [domain, plan])),
|
|
40
|
+
launchId: keccak256(encodeAbiParameters(parseAbiParameters("uint256,address,address,uint256"), [plan.chainId, plan.orchestrator, plan.creator, plan.nonce])),
|
|
41
|
+
domain, modes: ["atomic", "staged"],
|
|
42
|
+
};
|
|
43
|
+
const json = `${JSON.stringify(fixture, (_key, value) => typeof value === "bigint" ? value.toString() : value, 2)}\n`;
|
|
44
|
+
const outputs = process.argv.slice(2);
|
|
45
|
+
if (outputs.length === 0) process.stdout.write(json);
|
|
46
|
+
else {
|
|
47
|
+
for (const output of outputs) await writeFile(output, json);
|
|
48
|
+
console.log(JSON.stringify({ generated: outputs, planHash: fixture.planHash, launchId: fixture.launchId }));
|
|
49
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc20-abyss-basic", description: "ERC20, one canonical Abyss position, atomic opening",
|
|
5
|
+
tokenKind: 0, rewardMode: 0, mode: "atomic",
|
|
6
|
+
markets: [{ venue: "abyss", positions: 1 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc20-burn-mixed", description: "Burn policy, dual-fee V4 and Abyss markets for one token",
|
|
5
|
+
tokenKind: 0, rewardMode: 0, mode: "staged", burnBps: 3000,
|
|
6
|
+
markets: [{ venue: "v4", positions: 2, feeMode: 1 }, { venue: "abyss", positions: 1 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc20-dividends-abyss", description: "Holder dividends and three canonical Abyss positions",
|
|
5
|
+
tokenKind: 0, rewardMode: 2, mode: "staged",
|
|
6
|
+
markets: [{ venue: "abyss", positions: 3 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc20-staking-v4", description: "Staking rewards, two V4 positions and two ordered opening buys",
|
|
5
|
+
tokenKind: 0, rewardMode: 1, mode: "staged",
|
|
6
|
+
markets: [{ venue: "v4", positions: 2 }], buysPerMarket: 2,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc20-v4-basic", description: "ERC20, one pool-bound V4 position, atomic opening",
|
|
5
|
+
tokenKind: 0, rewardMode: 0, mode: "atomic",
|
|
6
|
+
markets: [{ venue: "v4", positions: 1 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc404-abyss", description: "ERC404 NFT units and metadata, atomic canonical Abyss",
|
|
5
|
+
tokenKind: 1, rewardMode: 0, mode: "atomic",
|
|
6
|
+
markets: [{ venue: "abyss", positions: 1 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc404-dividends-mixed", description: "ERC404 holder dividends, both venues and five permanent positions",
|
|
5
|
+
tokenKind: 1, rewardMode: 2, mode: "staged",
|
|
6
|
+
markets: [{ venue: "v4", positions: 2 }, { venue: "abyss", positions: 3 }], buysPerMarket: 1,
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { runLaunchExample } from "./launch-example.mjs";
|
|
2
|
+
|
|
3
|
+
await runLaunchExample({
|
|
4
|
+
id: "erc404-v4", description: "ERC404 NFT units and metadata, staged pool-bound V4",
|
|
5
|
+
tokenKind: 1, rewardMode: 0, mode: "staged",
|
|
6
|
+
markets: [{ venue: "v4", positions: 1 }], buysPerMarket: 1,
|
|
7
|
+
});
|