@black-market/sdk 0.10.0 → 0.12.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 (83) hide show
  1. package/README.md +21 -2
  2. package/dist/lifecycle/abi.d.ts +1 -0
  3. package/dist/lifecycle/abi.d.ts.map +1 -1
  4. package/dist/lifecycle/abi.js +1 -0
  5. package/dist/lifecycle/abi.js.map +1 -1
  6. package/dist/lifecycle/calibration.d.ts.map +1 -1
  7. package/dist/lifecycle/calibration.js +2 -0
  8. package/dist/lifecycle/calibration.js.map +1 -1
  9. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts +71 -0
  10. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts.map +1 -0
  11. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js +73 -0
  12. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js.map +1 -0
  13. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts +71 -0
  14. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts.map +1 -0
  15. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js +73 -0
  16. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js.map +1 -0
  17. package/dist/lifecycle/index.d.ts +1 -0
  18. package/dist/lifecycle/index.d.ts.map +1 -1
  19. package/dist/lifecycle/index.js +1 -0
  20. package/dist/lifecycle/index.js.map +1 -1
  21. package/dist/lifecycle/markets.d.ts +3 -1
  22. package/dist/lifecycle/markets.d.ts.map +1 -1
  23. package/dist/lifecycle/markets.js +20 -3
  24. package/dist/lifecycle/markets.js.map +1 -1
  25. package/dist/lifecycle/planner.d.ts.map +1 -1
  26. package/dist/lifecycle/planner.js +83 -54
  27. package/dist/lifecycle/planner.js.map +1 -1
  28. package/dist/lifecycle/presets.d.ts +9 -2
  29. package/dist/lifecycle/presets.d.ts.map +1 -1
  30. package/dist/lifecycle/presets.js +26 -5
  31. package/dist/lifecycle/presets.js.map +1 -1
  32. package/dist/lifecycle/progress.d.ts.map +1 -1
  33. package/dist/lifecycle/progress.js +26 -5
  34. package/dist/lifecycle/progress.js.map +1 -1
  35. package/dist/lifecycle/rpc.js +3 -2
  36. package/dist/lifecycle/rpc.js.map +1 -1
  37. package/dist/lifecycle/simulation.d.ts +1 -1
  38. package/dist/lifecycle/simulation.d.ts.map +1 -1
  39. package/dist/lifecycle/simulation.js +119 -175
  40. package/dist/lifecycle/simulation.js.map +1 -1
  41. package/dist/lifecycle/transactions.d.ts +6 -0
  42. package/dist/lifecycle/transactions.d.ts.map +1 -1
  43. package/dist/lifecycle/transactions.js +39 -0
  44. package/dist/lifecycle/transactions.js.map +1 -1
  45. package/dist/lifecycle/types.d.ts +17 -4
  46. package/dist/lifecycle/types.d.ts.map +1 -1
  47. package/dist/lifecycle/types.js.map +1 -1
  48. package/dist/lifecycle/ufg-abi.d.ts +2386 -0
  49. package/dist/lifecycle/ufg-abi.d.ts.map +1 -0
  50. package/dist/lifecycle/ufg-abi.js +171 -0
  51. package/dist/lifecycle/ufg-abi.js.map +1 -0
  52. package/dist/lifecycle/ufg-config.d.ts +38 -0
  53. package/dist/lifecycle/ufg-config.d.ts.map +1 -0
  54. package/dist/lifecycle/ufg-config.js +75 -0
  55. package/dist/lifecycle/ufg-config.js.map +1 -0
  56. package/dist/lifecycle/ufg.d.ts +21 -0
  57. package/dist/lifecycle/ufg.d.ts.map +1 -0
  58. package/dist/lifecycle/ufg.js +98 -0
  59. package/dist/lifecycle/ufg.js.map +1 -0
  60. package/docs/launch-lifecycle.md +215 -32
  61. package/examples/.env.example +4 -0
  62. package/examples/README.md +35 -2
  63. package/examples/launch-example-support.ts +1 -0
  64. package/examples/launch-example.ts +1 -0
  65. package/examples/launch.ts +1 -0
  66. package/examples/ufg-launch-config.ts +31 -0
  67. package/package.json +1 -1
  68. package/src/lifecycle/abi.ts +1 -0
  69. package/src/lifecycle/calibration.ts +1 -0
  70. package/src/lifecycle/deployments/ufg-dynamic-pool-20261021.ts +74 -0
  71. package/src/lifecycle/deployments/ufg-fixed-pool-20261021.ts +74 -0
  72. package/src/lifecycle/index.ts +1 -0
  73. package/src/lifecycle/markets.ts +16 -3
  74. package/src/lifecycle/planner.ts +75 -51
  75. package/src/lifecycle/presets.ts +27 -6
  76. package/src/lifecycle/progress.ts +22 -5
  77. package/src/lifecycle/rpc.ts +3 -2
  78. package/src/lifecycle/simulation.ts +114 -166
  79. package/src/lifecycle/transactions.ts +38 -1
  80. package/src/lifecycle/types.ts +15 -5
  81. package/src/lifecycle/ufg-abi.ts +173 -0
  82. package/src/lifecycle/ufg-config.ts +77 -0
  83. package/src/lifecycle/ufg.ts +86 -0
@@ -0,0 +1,98 @@
1
+ import { decodeFunctionResult, encodeFunctionData, keccak256, stringToHex, zeroAddress } from "viem";
2
+ import { lifecycleErc20Abi } from "./abi.js";
3
+ import { ufgLaunchProxyV1Abi, ufgTreasuryFactoryV1Abi } from "./ufg-abi.js";
4
+ import { buildLaunchTransactions } from "./transactions.js";
5
+ import { decodeAbyssLifecycleMarketConfig, encodeAbyssLifecycleMarketConfig, decodePoolBoundV4LifecycleMarketConfig } from "./markets.js";
6
+ import { getKnownLifecycleProfile, KnownLifecycleProfile } from "./presets.js";
7
+ import { LifecycleFundingKind, LifecycleTokenKind, LifecycleRewardMode, LifecycleMode } from "./schema.js";
8
+ import { LifecyclePlanningError } from "./types.js";
9
+ import { buildUfgFeeAssetPolicies, encodeUfgLaunchConfig, hashUfgLaunchConfig, isUfgProfile, UFG_DYNAMIC_ADAPTER_ID, UFG_FIXED_ADAPTER_ID, UFG_FIXED_PROFILE_ID, UFG_LAUNCH_PROXY_ADDRESS, UFG_TREASURY_FACTORY_ADDRESS, ufgPlanPrincipal } from "./ufg-config.js";
10
+ export { UFG_LAUNCH_PROXY_ADDRESS, UFG_TREASURY_FACTORY_ADDRESS, UFG_UPSTREAM_FACTORY_ADDRESS, UFG_ORCHESTRATOR_ADDRESS, UFG_FIXED_PROFILE_ID, UFG_DYNAMIC_PROFILE_ID, UFG_FIXED_ADAPTER_ID, UFG_DYNAMIC_ADAPTER_ID, isUfgProfile, ufgLaunchConfigComponents, encodeUfgLaunchConfig, decodeUfgLaunchConfig, hashUfgLaunchConfig, validateUfgLaunchConfig, ufgLaunchNonce, buildUfgFeeAssetPolicies } from "./ufg-config.js";
11
+ /** Offline proxy-specific admission. Live token/reserve code, registry and transfer checks still require simulation. */
12
+ export function validateUfgLaunchPlan(plan, config, predictedToken) {
13
+ try {
14
+ ufgPlanPrincipal(plan);
15
+ encodeUfgLaunchConfig(config);
16
+ if (plan.token.kind !== LifecycleTokenKind.ERC20 || plan.token.rewardMode !== LifecycleRewardMode.None || plan.executorFeeBps !== 0 || plan.markets.length === 0 || plan.token.inventoryRecipient.toLowerCase() === UFG_LAUNCH_PROXY_ADDRESS.toLowerCase() || plan.buys.some((buy) => buy.recipient.toLowerCase() === UFG_LAUNCH_PROXY_ADDRESS.toLowerCase()))
17
+ throw new Error("UFG requires ERC20/no rewards, zero executor fee, markets and external inventory/buy recipients");
18
+ const expected = buildUfgFeeAssetPolicies(predictedToken, config.reserveAssets);
19
+ if (plan.feeAssets.length !== expected.length || plan.feeAssets.some((policy, index) => {
20
+ const required = expected[index];
21
+ return policy.asset.toLowerCase() !== required.asset.toLowerCase() || policy.ownerBps !== required.ownerBps || policy.rewardsBps !== 0 || policy.burnBps !== required.burnBps;
22
+ }))
23
+ throw new Error("UFG fee policies must burn all token fees and send all reserve fees to the owner, in ascending asset order");
24
+ const reserves = new Set(config.reserveAssets.map((asset) => asset.toLowerCase()));
25
+ const quotes = new Set(plan.markets.map((market) => market.quoteAsset.toLowerCase()));
26
+ if (reserves.size !== quotes.size || [...quotes].some((quote) => !reserves.has(quote)))
27
+ throw new Error("Every reserve must be a market quote and every market quote a reserve");
28
+ const configHash = hashUfgLaunchConfig(config);
29
+ for (const market of plan.markets) {
30
+ if (market.configVersion === 1) {
31
+ const inner = decodeAbyssLifecycleMarketConfig(market.config);
32
+ const profile = getKnownLifecycleProfile({ chainId: plan.chainId, orchestrator: plan.orchestrator, key: inner.profile === 2 ? KnownLifecycleProfile.Abyss2 : KnownLifecycleProfile.Abyss3 });
33
+ if (market.adapterId.toLowerCase() !== keccak256(stringToHex("black-market.adapter.abyss-lifecycle.v1")) || (inner.profile !== 2 && inner.profile !== 3) || market.profileId.toLowerCase() !== profile?.profile.id || encodeAbyssLifecycleMarketConfig(inner).toLowerCase() !== market.config.toLowerCase())
34
+ throw new Error("UFG Abyss markets require canonical QUOTE or QUOTE_ORACLE config1 without a tail");
35
+ }
36
+ else if (market.configVersion === 6) {
37
+ if (!isUfgProfile(market.profileId))
38
+ throw new Error("UFG config6 markets require an admitted UFG fixed or dynamic profile");
39
+ const inner = decodePoolBoundV4LifecycleMarketConfig(market.config, 6);
40
+ const adapterId = market.profileId.toLowerCase() === UFG_FIXED_PROFILE_ID ? UFG_FIXED_ADAPTER_ID : UFG_DYNAMIC_ADAPTER_ID;
41
+ if (market.adapterId.toLowerCase() !== adapterId || inner.profileId.toLowerCase() !== market.profileId.toLowerCase() || inner.version !== 6 || inner.feeMode !== 1 || inner.lpFeePips !== 0 || inner.ufgLaunchConfig === undefined || hashUfgLaunchConfig(inner.ufgLaunchConfig) !== configHash)
42
+ throw new Error("Every UFG config6 market requires QuoteOnly, zero LP fee and the identical canonical proxy config tail");
43
+ }
44
+ else
45
+ throw new Error("UFG supports only canonical Abyss config1 and UFG pool-bound config6");
46
+ }
47
+ }
48
+ catch (error) {
49
+ if (error instanceof LifecyclePlanningError && error.code === "INVALID_UFG_PLAN")
50
+ throw error;
51
+ throw new LifecyclePlanningError("INVALID_UFG_PLAN", error instanceof Error ? error.message : "Invalid UFG launch plan");
52
+ }
53
+ }
54
+ /** Pure unsigned proxy commands; account is the principal encoded in plan.nonce. */
55
+ export function buildUfgLaunchTransactions(options) {
56
+ const { plan, config } = options;
57
+ const principal = ufgPlanPrincipal(plan);
58
+ encodeUfgLaunchConfig(config);
59
+ return buildLaunchTransactions(options).map((transaction) => {
60
+ const data = transaction.kind === "atomic" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "launchAtomic", args: [plan, config] })
61
+ : transaction.kind === "begin" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "beginLaunch", args: [plan, LifecycleMode.Staged, config] }) : transaction.data;
62
+ return { ...transaction, from: principal, to: UFG_LAUNCH_PROXY_ADDRESS, data, calldataBytes: (data.length - 2) / 2 };
63
+ });
64
+ }
65
+ export function buildUfgCancelTransaction({ plan, preparedMarkets = 0 }) {
66
+ const data = encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "cancelLaunch", args: [plan] });
67
+ return { id: "cancel", kind: "cancel", chainId: Number(plan.chainId), from: ufgPlanPrincipal(plan), to: UFG_LAUNCH_PROXY_ADDRESS, data, calldataBytes: (data.length - 2) / 2, value: 0n, dependencies: [], postconditions: [{ kind: "launch", phase: "Cancelled", preparedMarkets }] };
68
+ }
69
+ /** Exact summed proxy pulls, not escrow allowances. Current allowance/reset discovery belongs to planning. */
70
+ export function buildUfgApprovals(plan) {
71
+ const principal = ufgPlanPrincipal(plan);
72
+ const totals = new Map();
73
+ for (const funding of plan.funding) {
74
+ if (funding.kind === LifecycleFundingKind.NativeWrap || BigInt(funding.inputAsset) === 0n)
75
+ continue;
76
+ const asset = funding.kind === LifecycleFundingKind.ERC20 ? funding.asset : funding.inputAsset;
77
+ const amount = funding.kind === LifecycleFundingKind.ERC20 ? funding.amount : funding.inputAmount;
78
+ const key = asset.toLowerCase();
79
+ const entry = totals.get(key);
80
+ if (entry === undefined)
81
+ totals.set(key, { asset, amount });
82
+ else
83
+ entry.amount += amount;
84
+ }
85
+ const transactions = [...totals.values()].map(({ asset, amount }) => {
86
+ const data = encodeFunctionData({ abi: lifecycleErc20Abi, functionName: "approve", args: [UFG_LAUNCH_PROXY_ADDRESS, amount] });
87
+ return { id: `approve:${asset}`, kind: "approve", chainId: Number(plan.chainId), from: principal, to: asset, data, calldataBytes: (data.length - 2) / 2, value: 0n, dependencies: [], postconditions: [{ kind: "allowance", asset, spender: UFG_LAUNCH_PROXY_ADDRESS, minimum: amount }] };
88
+ });
89
+ return transactions.map((transaction, index) => ({ ...transaction, dependencies: index === 0 ? [] : [transactions[index - 1].id] }));
90
+ }
91
+ /** Read-only upstream treasury lookup. No treasury is represented by undefined, not the zero address. */
92
+ export async function readUfgTreasury(client, token) {
93
+ const data = encodeFunctionData({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", args: [token] });
94
+ const result = await client.request({ method: "eth_call", params: [{ to: UFG_TREASURY_FACTORY_ADDRESS, data }, "latest"] });
95
+ const treasury = decodeFunctionResult({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", data: result });
96
+ return treasury === zeroAddress ? undefined : treasury;
97
+ }
98
+ //# sourceMappingURL=ufg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ufg.js","sourceRoot":"","sources":["../../src/lifecycle/ufg.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,188 @@ The canonical authorities are the registry/certification/adapter/config contract
7
7
  in the protocol repository. Plan identity is `LaunchPlanV1`. Pool-bound V4 uses **config 6**,
8
8
  canonical Abyss uses **config 1**, and generic current shared-V4 support uses **config 4**.
9
9
 
10
+ ## 0.12.0 release: opt-in UFG treasuries
11
+
12
+ UFG is an additive **proxy launch route**, not a new token kind or a replacement
13
+ for the core path. Existing launch defaults, calldata, salts and HMM behavior are
14
+ unchanged when `ufg` is omitted. The pinned Robinhood deployment (chain **4663**) is:
15
+
16
+ | Export | Address |
17
+ | --- | --- |
18
+ | `UFG_LAUNCH_PROXY_ADDRESS` | `0xf6673d859DE03eB74A0b01696Edb97f941dFD0CA` |
19
+ | `UFG_TREASURY_FACTORY_ADDRESS` | `0x26Aa5D52134c8E6c4C01E9fb53A7568c0C64901F` |
20
+ | `UFG_UPSTREAM_FACTORY_ADDRESS` | `0xA170b5A58C111334A7237F2Ea2c428ec5022f68E` |
21
+ | `UFG_ORCHESTRATOR_ADDRESS` | `0x91560876033d568d25CDe98C78c33ff8FC43962c` |
22
+
23
+ `KnownLifecycleProfile.V4UfgFixedPool` (`v4-ufg-fixed-pool`) selects profile
24
+ `0x5c6045af480814e469f3dba7c120d264047c9320b869c63a064536041a2dbae6`;
25
+ `V4UfgDynamicPool` (`v4-ufg-dynamic-pool`) selects
26
+ `0x03de8d5e38f2957d80ecb9f2e59d555601ff091dfb17bce84178956a2e8d9b41`.
27
+ `isUfgProfile` recognizes only these IDs. Frozen envelopes, adapter/registration/
28
+ topology and bound-hook metadata come from committed registry readback at block
29
+ **94,551,140** (`test/fixtures/ufg-registry-readback.json`). Regenerate with
30
+ `node --experimental-transform-types scripts/generate-ufg-presets.mjs /path/to/black-market`;
31
+ add `--readback` only to recapture that exact block with read-only RPC.
32
+ The fixed and zero-royalty dynamic creation bytes exactly match the existing
33
+ `FixedFeePoolV1` / `DynamicFeePoolV1` artifacts, so no duplicate hook enum is needed.
34
+ UFG deployers, lockers, collectors and adapters are nevertheless different graphs.
35
+ Frozen presets are construction evidence, not live admission.
36
+
37
+ ### Configuration and supported markets
38
+
39
+ `UfgLaunchConfig` is `{ treasuryShareBps, exitFeeBps, reserveAssets }`. The proxy
40
+ requires treasury share **10000**, integer exit fee **0..2000 bps**, and **1..7**
41
+ nonzero, unique, strictly ascending reserve addresses, excluding the predicted
42
+ launch token. Reserves and market quotes must form exactly the same set.
43
+
44
+ - ERC20 only, no staking/dividends, zero executor fee and at least one market.
45
+ Neither inventory nor initial-buy recipients may be the proxy.
46
+ - Native Abyss uses the canonical adapter with config1 profile **2 (QUOTE)** or
47
+ **3 (QUOTE_ORACLE)** and the matching canonical profile ID. Its canonical
48
+ config has **no tail**.
49
+ - V4 uses config6 and one of the two UFG profiles, `feeMode: 1` (QuoteOnly) and
50
+ `lpFeePips: 0`. Preset zero-royalty terms still apply. Supply/position budgets,
51
+ price/ranges, oracle registration and ordinary lifecycle bounds are unchanged.
52
+ - Fee policies contain exactly the token plus reserves in ascending order:
53
+ token `{ ownerBps: 0, rewardsBps: 0, burnBps: 10000 }`, reserves
54
+ `{ ownerBps: 10000, rewardsBps: 0, burnBps: 0 }`.
55
+ `buildUfgFeeAssetPolicies(predictedToken, reserveAssets)` builds that exact set;
56
+ reserve ordering is validated, never silently repaired.
57
+
58
+ `encodeUfgLaunchConfig` encodes **one dynamic tuple**:
59
+ `abi.encode((uint16,uint16,address[]))`, including the leading `0x20` offset.
60
+ `decodeUfgLaunchConfig` checks canonical re-encoding; trailing bytes, alternate
61
+ offsets and dirty padding are rejected. `hashUfgLaunchConfig` is its keccak256.
62
+ Config6's typed `ufgLaunchConfig` automatically appends that encoding after the
63
+ canonical V6 prefix and decodes/splits it on read. Every UFG V4 tail must equal
64
+ the proxy config. The constructor economics hash remains **prefix-only with zero
65
+ hook salt**; the full plan hash binds the tail. No UFG tail is added to ordinary
66
+ V4, HMM or Abyss configs. Independent `cast abi-encode` fixtures are regenerated
67
+ with `node scripts/generate-ufg-fixtures.mjs`.
68
+
69
+ ### Principal funding, planning and recovery
70
+
71
+ The economic plan's **creator is the proxy**. Its nonce is
72
+ `ufgLaunchNonce(principal, nonce96) = (uint160(principal) << 96) | nonce96`.
73
+ The `account` and every sender are the **same principal**, never the proxy.
74
+ The core still derives launch ID/token from the committed core/proxy/nonce.
75
+
76
+ ```ts
77
+ const config = {
78
+ treasuryShareBps: 10000, exitFeeBps: 100,
79
+ reserveAssets: [getAddresses(4663).weth],
80
+ };
81
+ // economicPlan already contains your full token/funding/market/buy economics;
82
+ // every UFG V4 market was encoded with this same ufgLaunchConfig.
83
+ const plan = { ...economicPlan, creator: UFG_LAUNCH_PROXY_ADDRESS,
84
+ nonce: ufgLaunchNonce(principal, 1n) };
85
+ const token = await client.readContract({ address: plan.orchestrator,
86
+ abi: launchLifecycleAbi, functionName: "predictToken", args: [plan] });
87
+ plan.feeAssets = buildUfgFeeAssetPolicies(token, config.reserveAssets);
88
+ validateUfgLaunchPlan(plan, config, token); // pure/offline proxy rules
89
+ const planned = await prepareAndPlanLifecycleLaunch({
90
+ client, account: principal, plan, mode: "staged", ufg: { config },
91
+ });
92
+ // No signing here. Obtain fresh admitted proxy envelopes before wallet execution:
93
+ const next = await buildNextTransaction({ client, planned });
94
+ ```
95
+
96
+ The opt-in works on `planLaunch` too. `PlannedLaunch.ufg` retains config and its
97
+ hash; `simulateLaunchPlan`, `readLaunchProgress`, and `buildNextTransaction`
98
+ (including `action: "cancel"`) retain the route and reject config mutation,
99
+ wrong principal/nonce, wrong receipt target/config, or proxy binding mismatch.
100
+ Salt mining and optional buy-minimum calibration use the existing machinery.
101
+ Native Nitro metering/execution proofs remain mandatory on production chain4663.
102
+
103
+ The proxy pulls summed non-native inputs from the principal: ERC20 asset/amount
104
+ or swap inputAsset/inputAmount. **Approve the proxy, not the funding escrow**.
105
+ `buildUfgApprovals(plan)` builds exact summed approvals; planning observes current
106
+ allowances and includes zero-reset commands when needed. Native-wrap and native
107
+ swap inputs are `msg.value` on atomic/begin only. Refunds return to the principal.
108
+
109
+ Pure `buildUfgLaunchTransactions({ plan, config, mode, preparationBatches })`
110
+ produces proxy `launchAtomic(plan, config)`, or `beginLaunch(plan, Staged, config)`,
111
+ ordered `prepareMarkets` batches, then `activateLaunch`. The explicit batches
112
+ must cover all markets. `buildUfgCancelTransaction({ plan, preparedMarkets })`
113
+ targets the same proxy. These builders alone do not establish execution admission.
114
+ `validateUfgLaunchPlan` checks offline proxy rules; live registry continuity,
115
+ reserve/token code and supply bounds, transfers and treasury creation require RPC
116
+ simulation. The existing non-UFG core transaction builder is intentionally unchanged.
117
+
118
+ `readUfgTreasury(client, token)` reads the treasury factory's `treasuryOf(token)`
119
+ and returns the upstream address, or `undefined` for zero. Complete
120
+ `ufgLaunchProxyV1Abi`, `ufgTreasuryFactoryV1Abi`, `ufgBlackMarketFactoryAbi` and
121
+ `ufgBlackMarketTreasuryAbi` expose proxy config hashes and upstream treasury
122
+ collect/redeem/assets/backing/position/debt operations without inventing wrappers.
123
+ The pure example is `node examples/ufg-launch-config.ts` after building.
124
+
125
+ ### UFG owned-fork check
126
+
127
+ This explicitly authorized local-only integration uses the unlocked Anvil default
128
+ account, no keys, and only public SDK launch APIs. In separate terminals:
129
+
130
+ ```sh
131
+ anvil --fork-url https://rpc.mainnet.chain.robinhood.com/ \
132
+ --chain-id 4663 --port 8561 \
133
+ --gas-limit 100000000 --silent
134
+ pnpm build
135
+ UFG_FORK_RPC_URL=http://127.0.0.1:8561 node test/integration/ufg-launch.fork.mjs
136
+ ```
137
+
138
+ It validates the tuple against the deployed factory, mines bound-hook salts,
139
+ executes Abyss QUOTE atomic, mixed Abyss QUOTE + UFG fixed staged (ERC20 funding/
140
+ proxy approval), and UFG dynamic atomic launches. It calls each exact proxy
141
+ command from the principal first, then checks Active, a nonzero `readUfgTreasury`
142
+ and `proxy.launchConfigHash == hashUfgLaunchConfig`. Snapshot restoration makes
143
+ the check repeatable. Stop Anvil afterward. Generic Anvil proves EVM contract
144
+ behavior here, **not ArbOS compute/poster admission**: construction/read/mining/
145
+ unsigned APIs plus actual fork `eth_call`/receipts are used, not a fake native
146
+ Nitro planner certificate. Ordinary `pnpm test` never runs this funded check.
147
+
148
+ ## 0.11.0 release: gas sizing, packing and prefix proof
149
+
150
+ New atomic/activation envelopes containing HMM V2 markets add one forwarding target:
151
+ `R = 4_250_000 + 500_000 * (hmmMarkets - 1)` gas (zero for non-HMM plans).
152
+ For measured gross gas `G` (`maxUsedGas`, falling back to `gasUsed`), compute is
153
+ `min(max(G + R, ceil(G * (10000 + headroomBps) / 10000)), computeCap)`.
154
+ Begin/preparation/approval/cancel commands do not receive this reserve. Nitro poster
155
+ gas is budgeted separately inside the same complete gas envelope. Optional padding
156
+ and the reserve are targets, not refusal thresholds; exact validated replay proves
157
+ the clamped envelope. There is no bisection or extra ordinary-path request.
158
+
159
+ Staged planning greedily packs contiguous markets against the unpadded compute cap:
160
+ HMM V2 costs 14.5M per market; other profiles cost a conservative 16M. At 32M,
161
+ 1/2/3/5 HMM markets produce `[1]`/`[2]`/`[2,1]`/`[2,2,1]`.
162
+ Only a packed measurement failure consuming at least 95% of its given gas splits
163
+ that batch in half, regardless of its error selector. Low-gas semantic failures
164
+ remain failures. `preparationBatchSize` is removed; inspect each preparation's
165
+ `marketStart`/`marketCount`. The pure unsigned compiler still accepts explicit
166
+ `preparationBatches`.
167
+
168
+ Robinhood chain 4663 defaults `limits.maxSimulationGas` to **50_000_000n** aggregate
169
+ gas **used**, not the sum of individual legal transaction envelopes. Override it
170
+ for a provider with a different budget. The SDK measures and validates the longest
171
+ estimated prefix that fits: begin 9.5M, preparations as above, activation 6M per
172
+ market plus `R`, and small approvals/cancellation. A measurement failure after
173
+ cumulative use reaches 95% of that cap defers the failed call and suffix.
174
+ If even the immediate estimate cannot fit that budget, refusal first identifies
175
+ any estimated per-transaction compute overflow (gas displayed in millions to one
176
+ decimal), rather than suggesting that a larger RPC budget solves it. Estimates
177
+ alone do not reject an envelope that can still be measured and exactly proved.
178
+
179
+ `simulation.admitted`, `executionProof: "proved"` and `protocolFit: "proved"` cover
180
+ only the successful proven prefix. **They do not promise eventual activation.**
181
+ `simulation.deferredTransactionIds` explicitly lists unproved remaining steps
182
+ (empty for full coverage); these commands carry no `gas`, `gasPrice`, `estimate`
183
+ or `admission`. Call `buildNextTransaction` before each signature: canonical
184
+ progress advances the proof window and gives the immediate next transaction exact
185
+ gas. Reviewed envelopes receive only a direct exact replay of that immediate step,
186
+ without new measurement, poster/price recommendations or suffix proof.
187
+
188
+ `buySlippageBps` requires actual activation outputs. If activation is deferred,
189
+ calibration refuses clearly; use a higher-budget native provider or preserve
190
+ already committed minima by omitting recalibration. Outputs are never fabricated.
191
+
10
192
  ## 0.9.1 release: Abyss 0.01% fee tier
11
193
 
12
194
  `ABYSS_FEE_TIERS` now includes `{ feePips: 100, tickSpacing: 1, label: "0.01%" }`.
@@ -342,15 +524,13 @@ progress, funding/allowances and deployment/profile authority. It matches
342
524
  Preparation batching remains SDK-derived, not caller-selected. Malformed,
343
525
  wrong-step or changed envelopes refuse without returning executable calldata.
344
526
 
345
- Fresh measurement and complete native validated replay use the held price.
346
- The immediate replay uses the exact held gas; later unfinished steps receive
347
- fresh gas bounds and remain in the same stateful sequence. Current compute,
348
- poster, minimum headroom, tightening ceilings and full-sequence actual-balance
349
- affordability still apply. Exact replay also checks gross-gas headroom without
350
- counting Nitro's temporary compute hold. Neither natural child base fees nor
351
- payer balances are overridden. A higher advisory quote alone is not a refusal;
352
- an invalid current fee, insufficient gas or failed proof never silently raises
353
- the held envelope.
527
+ The SDK directly validates only the immediate transaction at its exact held
528
+ gas/price. It does not repeat measurement, quote a new gas price/poster budget or
529
+ simulate future steps. Current protocol/transaction limits, native metering,
530
+ postconditions and immediate actual-balance affordability still apply. Existing
531
+ padding may be consumed; neither a new padding target nor a higher advisory quote
532
+ alone invalidates a held envelope. Natural child base fees and payer balances are
533
+ never overridden, and failed replay never raises held gas or switches backend.
354
534
 
355
535
  Approvals/resets, atomic launches, every staged next step and cancellation use
356
536
  this same contract. Cancellation retains its adapter-independent recovery policy.
@@ -742,13 +922,13 @@ Validation uses `validateV4LifecycleMarket`; the collector factory getter is
742
922
  | --- | --- |
743
923
  | `readLifecycleProfiles({client, orchestrator, profileIds?, offset?, limit?})` | Bounded registry discovery, schema/topology dispatch, reviewed graph/terms certification and current registry admission. Default offset/limit is 0/100; explicit IDs can select a reviewed deployment's identities. |
744
924
  | `predictLifecycleToken({client, plan})` | Exact prediction from the explicit core. |
745
- | `prepareAndPlanLifecycleLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market launch topology and exact final deployment bindings, and returns complete selected-mode admission under one SDK-owned fresh post-mining snapshot. No source-chain deployment or broadcast. |
925
+ | `prepareAndPlanLifecycleLaunch({client, account, plan, mode, buySlippageBps?, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market topology and exact final deployment bindings, and proves the selected-mode prefix under one fresh post-mining snapshot. Reports deferred steps; buy calibration requires activation coverage. No source-chain deployment or broadcast. |
746
926
  | `readPoolBoundHookDeployment({client, plan, marketIndex})` | Verifies typed factory, code chunks, constructor, normalized economics, initcode, salt, CREATE2 prediction and recorded provenance of existing code. Works with draft salts; permission bits are additionally required for executable predeployment. |
747
927
  | `buildPoolBoundHookDeploymentTransaction({client, plan, marketIndex})` | Optional permissionless typed `deploy(parameters,salt)` calldata. Does not create a token, register/initialize a pool, bind a collector or activate a launch. |
748
928
  | `planLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?})` | Independently fresh per-market topology/domain/funding/profile/progress/execution admission of the already-finalized commitment, simulating only the explicitly selected mode. |
749
929
  | `simulateLaunchPlan({client, planned, limits?, fork?, receipts?, confirmations?})` | Rereads canonical state and proves remaining work. Preserves receipt evidence, economics and selected mode. |
750
930
  | `readLaunchProgress({client, planned, receipts?, confirmations?})` | Confirmation-bound canonical state, latest head, receipt/replacement/reorg status, account-nonce safety and actual prepared market/live state. |
751
- | `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads progress, constraints and complete stateful proof before returning one admitted transaction. Optional untrusted `reviewedTransaction` must match the current canonical next step and freshly prove its exact gas/price. Optional `submissionClient` adds read-only immediate exact-envelope preflight. `action: "cancel"` uses the stored commitment without requiring fresh adapter/profile admission. Terminal launches return `undefined`. |
931
+ | `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads canonical progress and constraints, proves the immediate next transaction plus the fitting prefix, and returns one admitted envelope. With `reviewedTransaction`, directly replays only that matching immediate step at its exact held gas/price. Optional `submissionClient` adds read-only exact-envelope preflight. `action: "cancel"` retains adapter-independent recovery. Terminal launches return `undefined`. |
752
932
 
753
933
  Clients may be viem public clients or raw `request({method,params})` RPC clients. Transport, wallet, signing and durable storage are application-owned. `PlannedLaunch` contains bigint values and live limit callbacks: persist `serializeLaunchPlan(plan)`, explicit execution mode, confirmation policy and receipt references, not the entire object.
754
934
 
@@ -879,17 +1059,17 @@ Mining is cancellable/nonblocking; `abort()` raises `AbortError` and does not ca
879
1059
  Every planning call requires `mode: "atomic" | "staged"`. Only that requested mode receives economic simulation; staged does not compute or expose an unused atomic attempt.
880
1060
 
881
1061
  - Atomic: after funding prerequisites, token creation, empty infrastructure, all mint/lock/buys/public activation are one transaction.
882
- - Staged: prerequisites, `beginLaunch(Staged)`, contiguous empty `prepareMarkets` batches, then one `activateLaunch`. Only a stateful preparation refusal classified as capacity with a compute or gas-envelope constraint can partition into smaller empty batches. Opaque `DeploymentFailed`, unclassified/source/provider-clamp errors, byte-cap refusals and near-cap consumption do not authorize that search. Core/validator/registry/hook invariant errors stop planning.
1062
+ - Staged: prerequisites, `beginLaunch(Staged)`, greedily packed contiguous empty `prepareMarkets` batches, then one `activateLaunch`. A packed measurement failure using at least 95% of its given gas splits only that batch; low-gas semantic errors, byte caps and unlocated provider failures do not justify a split. Proof may cover only a prefix, with the unproved suffix explicitly deferred.
883
1063
  - Activation cannot split. If mint/lock/all buys/opening cannot fit, staged is also refused. No position/buy/minimum is omitted to manufacture success.
884
1064
 
885
1065
  No automatic atomic-to-staged fallback exists. Obtain separate consent to review the same commitment as staged. Both venues use token transfer restrictions plus activation-time canonical opening-state checks, not a pool gate. Manipulated opening price or preactivation liquidity fails verification; the token stays inactive and the launch remains Ready/cancellable. Failed activation rolls back every mint, seal, buy and opening together.
886
1066
 
887
1067
  ## Execution constraints and stateful simulation
888
1068
 
889
- Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit`, `maxCalldataBytes` and
890
- `maxSimulationGas` tighten admission when supplied. Missing policy remains explicit in
891
- `limits.unknownExecutionConstraints`/`unknownConstraints`; it does not reject an otherwise
892
- proved exact sequence or invent a provider/account cap. No policy service is required.
1069
+ Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit` and `maxCalldataBytes`
1070
+ tighten admission. `maxSimulationGas` sets the aggregate used-gas proof-window
1071
+ budget (default 50M on 4663, unknown on other chains). Missing policy stays explicit
1072
+ in `limits.unknownExecutionConstraints`/`unknownConstraints`; no policy service is required.
893
1073
  A `LifecycleLimitSource` callback receives the canonical chain/account/core/block context.
894
1074
  Any supplied provenance must match it; stale/mismatched/malformed facts or a failed supplied
895
1075
  resolver reject rather than disappearing into optional uncertainty. Gas caps are positive
@@ -897,7 +1077,9 @@ exact uint64 `bigint`; calldata is a positive safe integer byte count.
897
1077
  Reviewed gas envelopes are positive uint64 too; zero-metering observations cannot admit
898
1078
  a zero-gas transaction. Headroom calculations retain wide exact bigint intermediates.
899
1079
 
900
- Headroom defaults to 1,500 bps, bounded 0–10,000. Generic EVM admission uses the pinned
1080
+ Headroom defaults to 1,500 bps, bounded 0–10,000; it clamps to current legal ceilings
1081
+ instead of rejecting a fitting measured requirement. HMM V2 adds the forwarding
1082
+ target documented above once on atomic/activation. Generic EVM admission uses the pinned
901
1083
  bounded header and supplied total-envelope restrictions plus actual validated RPC proof.
902
1084
  It reports an absent independent per-transaction cutoff honestly, without importing a
903
1085
  universal Ethereum cutoff. `executionGasCeiling` and `transactionGasCeiling` are equal on
@@ -910,8 +1092,8 @@ carries that successfully replayed ceiling, never a smaller unproved envelope.
910
1092
  Replay source, HTTP and malformed-response failures remain provisional with
911
1093
  `executionProof: "unavailable"` and do not retry economic execution. `AbortError`
912
1094
  propagates unchanged, including cancellation during supplied policy and Nitro getter
913
- reads. A recognized execution refusal may discover at most one genuinely larger
914
- validated envelope within the same legal compute/total limits. Without returned
1095
+ reads. Only explicit genuine native out-of-gas evidence may discover at most one
1096
+ larger validated envelope within the same legal compute/total limits. Without returned
915
1097
  failing-call evidence, `failedTransactionId` stays absent; an opaque RPC error does
916
1098
  not invent a failing transaction or authorize preparation partitioning.
917
1099
  Returned failures retain the actual exact-replay prefix and its first failing
@@ -949,10 +1131,10 @@ The buffered compute-discovery envelope plus buffered poster budget is carried i
949
1131
  exact validated replay; an approximate poster quote is never subtracted from total
950
1132
  gas use to certify exact compute fit.
951
1133
  Measurement waits for successful capability and candidate-specific poster evidence,
952
- then uses the legal complete compute-plus-poster envelope. Near-cap gas consumption
953
- does not diagnose OOG, constructor failure or collision. Unsupported/transport
954
- evidence remains unavailable, and only a recognized execution-envelope refusal
955
- can trigger bounded envelope discovery.
1134
+ then uses the legal complete compute-plus-poster envelope. A packed preparation
1135
+ failure consuming at least 95% may invalidate its cost estimate without claiming
1136
+ its selector diagnoses OOG. Unsupported/transport evidence remains unavailable,
1137
+ except an observed aggregate-budget exhaustion can preserve a successful prefix.
956
1138
 
957
1139
  A separate pinned validated simulation probes all three ArbOS/version/getter values
958
1140
  against the canonical observations. Only that isolated capability probe temporarily
@@ -975,13 +1157,13 @@ does not manufacture an all-in estimate. All observations and limits refresh for
975
1157
  For initial construction, the exact legacy gas-price envelope is the greater of
976
1158
  the fresh RPC recommendation and twice the pinned base fee. This avoids
977
1159
  underpriced submission when `eth_gasPrice` lags the block base fee. Reviewed
978
- envelopes retain their exact gas/price only after fresh full-sequence measurement,
979
- native validated replay, current minimum headroom and affordability checks.
1160
+ envelopes retain exact gas/price through direct immediate native validated replay
1161
+ and immediate affordability, without repeating measurement or applying new padding.
980
1162
  The held price need not equal a new recommendation or twice the current base fee;
981
1163
  natural child fees and the actual submission estimate must accept it. Replay,
982
1164
  affordability and submission use that same price, without a base-fee override.
983
- A known aggregate budget whose legal minimum already exceeds its ceiling refuses
984
- before capability probes or poster work; equality is allowed. A definitive returned
1165
+ An aggregate budget selects the longest fitting estimated prefix; only when even
1166
+ the immediate estimate does not fit is no proof possible. A definitive returned
985
1167
  failure from the final exact replay skips a later payer-balance lookup, while
986
1168
  retaining fee/estimate validation and final canonical checks. Successful replay
987
1169
  still requires current actual-balance affordability.
@@ -1013,14 +1195,15 @@ Simulation and `next.admission` carry flat, independent proof outcomes:
1013
1195
 
1014
1196
  | Field | Values | Scope |
1015
1197
  | --- | --- | --- |
1016
- | `executionProof` | `"proved"`, `"failed"`, `"unavailable"` | Complete stateful exact-envelope execution and postconditions, never permissive measurement alone. |
1198
+ | `executionProof` | `"proved"`, `"failed"`, `"unavailable"` | Stateful exact-envelope execution/postconditions for the proven prefix (or the immediate reviewed step), never measurement alone or an unproved suffix. |
1017
1199
  | `protocolFit` | `"proved"`, `"failed"`, `"unknown"` | Applicable proven protocol and known tightening restrictions. Missing optional policy remains separately disclosed. |
1018
1200
  | `transportPreflight` | `"not-requested"`, `"passed"`, `"failed"` | Immediate exact next-transaction acceptance estimate on the supplied submission RPC. |
1019
1201
 
1020
- `admitted` means the current exact sequence is proved to fit and affordable; it is
1021
- not guaranteed wallet submission or future execution. Admission reuses simulation
1022
- `blockNumber`, `blockHash`, `account`, `chainId` and `limits`. Plans never preflight
1023
- future dependent transactions against state that does not exist.
1202
+ `admitted` means the proven prefix fits and is affordable, not that deferred
1203
+ transactions have executed or that eventual activation is guaranteed. Always
1204
+ inspect `simulation.deferredTransactionIds`. Admission reuses `blockNumber`,
1205
+ `blockHash`, `account`, `chainId` and `limits`; signing uses only fresh build-next
1206
+ admission. Plans never preflight future steps independently against nonexistent state.
1024
1207
 
1025
1208
  ```ts
1026
1209
  const planned = await planLaunch({ client, account: plan.creator, plan, mode: "atomic" });
@@ -35,3 +35,7 @@ NFT_BASE_URI=
35
35
  # EXAMPLE_ACCOUNT_GAS_CAP=
36
36
  # EXAMPLE_MAX_CALLDATA_BYTES=
37
37
  # EXAMPLE_HEADROOM_BPS=1500
38
+ #
39
+ # Robinhood aggregate simulation gas-used budget defaults to 50M. Override only for
40
+ # a provider supporting that budget; buy-output calibration needs activation coverage.
41
+ # EXAMPLE_SIMULATION_GAS_CAP=100000000
@@ -1,8 +1,8 @@
1
1
  # Examples
2
2
 
3
- The launch examples use the public `@black-market/sdk` 0.9.0 package and viem.
3
+ The launch examples use the public `@black-market/sdk` 0.12.0 package and viem.
4
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.
5
+ `@black-market/sdk@0.12.0` for opt-in UFG treasuries and current proof semantics.
6
6
  The default chain-4663 launch cases retain
7
7
  the October8 mined fixed pool-bound V4 config6/V2 and canonical Abyss config1 deployment.
8
8
  The SDK additionally knows the October11 zero-author-royalty Dynamic Fee Hook;
@@ -25,11 +25,25 @@ examples; their relative support imports use explicit `.ts` extensions for Node
25
25
  | --- | --- |
26
26
  | `quickstart.ts` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
27
27
  | `hmm-launch-config.ts` | Pure HMM V2 fixed/dynamic config construction with caller-chosen bid/reference guards and an automatically appended 512-byte launch tail; no RPC, signatures or writes. |
28
+ | `ufg-launch-config.ts` | Pure fixed/dynamic UFG quote-only config6 construction, canonical reserve tail and config hash; no RPC, wallet or writes. |
28
29
  | `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. |
29
30
  | `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. |
30
31
  | `launch-lifecycle-smoke.ts` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
31
32
  | `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. |
32
33
 
34
+ ## UFG treasury configuration
35
+
36
+ Run `pnpm build && node examples/ufg-launch-config.ts` for a pure consumer example.
37
+ Real UFG plans use the proxy as creator and a principal-namespaced nonce, with
38
+ `ufg: { config }` on `prepareAndPlanLifecycleLaunch`; the principal remains the
39
+ planning/signing account. Use only reward-free ERC20, full treasury reserve share,
40
+ launch-token burn policies, Abyss QUOTE/QUOTE_ORACLE or the UFG fixed/dynamic
41
+ presets. Approvals go to the proxy. The existing eleven launch cases and their
42
+ selected non-UFG offerings are intentionally unchanged.
43
+
44
+ The opt-in owned-fork regression is `test/integration/ufg-launch.fork.mjs`; see the
45
+ [lifecycle guide](../docs/launch-lifecycle.md#ufg-owned-fork-check).
46
+
33
47
  ## Deployed read-only discovery
34
48
 
35
49
  ```sh
@@ -73,6 +87,18 @@ generic EVM, not as a Nitro metering substitute. Unsigned review reports
73
87
  RPC to build-next. See the
74
88
  [lifecycle guide](../docs/launch-lifecycle.md#execution-constraints-and-stateful-simulation).
75
89
 
90
+ Robinhood defaults to a 50M aggregate simulation gas-used budget. Inspect
91
+ `simulation.deferredTransactionIds`: admitted/proved means the proven prefix,
92
+ not every future transaction or eventual activation. Deferred commands have no
93
+ gas/price/estimate/admission; obtain each fresh immediate envelope through
94
+ `buildNextTransaction` after canonical progress advances. Reviewed envelopes are
95
+ replayed directly, without measuring/replaying the suffix again. The saved-plan
96
+ CLI prints proof coverage and never signs. Override `limits.maxSimulationGas` only
97
+ for a provider that supports the selected budget. Examples requiring actual
98
+ activation outputs for `buySlippageBps` or economic review refuse if activation is
99
+ deferred; use a suitably higher-budget provider rather than inventing buy outputs.
100
+
101
+
76
102
  For a real new graph, create the saved plan using `readLifecycleProfiles` with its
77
103
  explicit chain/core and admitted pool-bound config6 profile. Supply that graph's RPC
78
104
  to `launch.ts`; do not substitute the historical known preset. Applications may use
@@ -381,6 +407,13 @@ to tighten the complete transaction envelope: `EXAMPLE_CHAIN_GAS_CAP`,
381
407
  restrictions, not invented provider/account assurances or admission bypasses.
382
408
  Poster allocation is already inside Nitro gas/affordability and is not charged twice.
383
409
 
410
+ Robinhood's separate aggregate simulation gas-used budget defaults to **50M**.
411
+ `EXAMPLE_SIMULATION_GAS_CAP` overrides that budget (positive decimal gas) for
412
+ providers supporting more or less. It does not change per-transaction compute
413
+ capacity. Multi-step examples requiring full activation outputs for buy protection
414
+ and economic review need a provider/budget covering activation, or refuse before
415
+ signing; do not raise the setting beyond the provider's actual supported budget.
416
+
384
417
  ### Evidence and failure recovery
385
418
 
386
419
  Each dry run or broadcast automatically creates `launch-results/<timestamp-case-random>/`;
@@ -540,6 +540,7 @@ export async function readExampleConfiguration(sdk, redactor, env = process.env)
540
540
  chainTransactionGasLimit: gasCap("EXAMPLE_CHAIN_GAS_CAP"),
541
541
  rpcTransactionGasLimit: gasCap("EXAMPLE_RPC_GAS_CAP"),
542
542
  accountTransactionGasLimit: gasCap("EXAMPLE_ACCOUNT_GAS_CAP"),
543
+ rpcTotalSimulationGasLimit: gasCap("EXAMPLE_SIMULATION_GAS_CAP"),
543
544
  maxCalldataBytes: integer("EXAMPLE_MAX_CALLDATA_BYTES", undefined, 1, Number.MAX_SAFE_INTEGER),
544
545
  headroomBps: integer("EXAMPLE_HEADROOM_BPS", 1500, 0, 10000),
545
546
  provenance: { scope: "user-ceilings", note: "Optional local tightening restrictions, not verified provider or account limits" },
@@ -477,6 +477,7 @@ function limitSource(fixture, artifacts) {
477
477
  chainGasLimit: policy.chainTransactionGasLimit === undefined ? undefined : BigInt(policy.chainTransactionGasLimit),
478
478
  rpcGasLimit: policy.rpcTransactionGasLimit === undefined ? undefined : BigInt(policy.rpcTransactionGasLimit),
479
479
  accountGasLimit: policy.accountTransactionGasLimit === undefined ? undefined : BigInt(policy.accountTransactionGasLimit),
480
+ maxSimulationGas: policy.rpcTotalSimulationGasLimit === undefined ? undefined : BigInt(policy.rpcTotalSimulationGasLimit),
480
481
  maxCalldataBytes: policy.maxCalldataBytes, headroomBps: policy.headroomBps,
481
482
  };
482
483
  artifacts.event("execution-limits", { limits, provenance: policy.provenance });
@@ -30,6 +30,7 @@ const options = { client, account: plan.creator, plan, mode, limits, fork, recei
30
30
  const planned = args.includes("--mine")
31
31
  ? await prepareAndPlanLifecycleLaunch({ ...options, onProgress: ({ marketIndex, attempts }) => console.error("salt mining", marketIndex, attempts.toString()) })
32
32
  : await planLaunch(options);
33
+ console.error("Proof coverage:", planned.simulation.steps.length, "steps; deferred:", planned.simulation.deferredTransactionIds);
33
34
  const progress = await readLaunchProgress({ client, planned, receipts, confirmations });
34
35
  const next = planned.simulation.admitted ? await buildNextTransaction({ client, planned, limits, fork, receipts, confirmations }) : undefined;
35
36
  console.log(JSON.stringify({ plan: JSON.parse(serializeLaunchPlan(planned.plan)), mode,
@@ -0,0 +1,31 @@
1
+ // Pure configuration example; no RPC, wallet, key, signing or broadcast.
2
+ // This is not a priced/admitted plan. Use core.predictToken(plan) for real fee policies,
3
+ // derive funded one-sided positions, then prepareAndPlanLifecycleLaunch({ ..., ufg: { config } }).
4
+ import { encodeAbiParameters, keccak256, zeroHash } from "viem";
5
+ import {
6
+ getAddresses, KnownLifecycleProfile, getKnownLifecycleProfile,
7
+ UFG_ORCHESTRATOR_ADDRESS, UFG_LAUNCH_PROXY_ADDRESS, encodeUfgLaunchConfig,
8
+ hashUfgLaunchConfig, encodePoolBoundV4LifecycleMarketConfig,
9
+ } from "@black-market/sdk";
10
+
11
+ const identity = { chainId: 4663n, orchestrator: UFG_ORCHESTRATOR_ADDRESS };
12
+ const config = { treasuryShareBps: 10000, exitFeeBps: 100, reserveAssets: [getAddresses(4663).weth] };
13
+ for (const key of [KnownLifecycleProfile.V4UfgFixedPool, KnownLifecycleProfile.V4UfgDynamicPool]) {
14
+ const preset = getKnownLifecycleProfile({ ...identity, key })!;
15
+ const envelope = preset.profile.envelope!;
16
+ const encoded = encodePoolBoundV4LifecycleMarketConfig({
17
+ version: 6, lpFeePips: 0, tickSpacing: 60, sqrtPriceX96: 1n << 96n,
18
+ hookFeePips: 10000, minimumHookFeePips: 1000, feeSensitivityPipsSecondsPerTick: 7654321,
19
+ feeMode: 1, protocolFeeDenominator: envelope.protocolFeeDenominator,
20
+ treasury: envelope.protocolTreasury, externalLiquidityDisabled: false,
21
+ oracleConfigId: keccak256(encodeAbiParameters([{ type: "uint24" }, { type: "uint16" }], [1, 4096])),
22
+ hookSalt: zeroHash, profileId: preset.profile.id, termsDigest: envelope.termsDigest,
23
+ developerBeneficiary: envelope.beneficiary, developerFeeBps: 0,
24
+ // Geometry/price are illustrative. Real launch uses predicted token ordering and budget-funded ranges.
25
+ positions: [{ tickLower: 0, tickUpper: 887220, liquidity: 1000n, salt: zeroHash, maxTokenAmount: 1000000n }],
26
+ ufgLaunchConfig: config,
27
+ });
28
+ console.log(key, { proxy: UFG_LAUNCH_PROXY_ADDRESS, profileId: preset.profile.id,
29
+ configBytes: (encoded.length - 2) / 2, tailBytes: (encodeUfgLaunchConfig(config).length - 2) / 2,
30
+ launchConfigHash: hashUfgLaunchConfig(config) });
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@black-market/sdk",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "TypeScript SDK for Abyss token launches, swaps, and lending.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -6,6 +6,7 @@ import {
6
6
  } from "./schema.js";
7
7
  import { poolBoundHookParametersV1Components, poolBoundHookParametersV2Components, v4LifecycleMarketComponents } from "./markets.js";
8
8
  export { hmmLiquidityManagerV2Abi, hmmFeeCollectorV2Abi, hmmFeeCollectorFactoryV2Abi, hmmFixedHookV2Abi, hmmDynamicHookV2Abi } from "./hmm-abi.js";
9
+ export { ufgLaunchProxyV1Abi, ufgTreasuryFactoryV1Abi, ufgBlackMarketFactoryAbi, ufgBlackMarketTreasuryAbi } from "./ufg-abi.js";
9
10
 
10
11
  const planInput = { name: "plan", type: "tuple", components: launchPlanV1Components } as const;
11
12
  export const launchLifecycleAbi = [