import { Address, Hex, PublicClient, BlockTag, WalletClient, Account, Hash, TransactionReceipt } from 'viem'; import { S as SdkTransactionResult } from './transaction-BiLcoXyx.js'; /** * Addresses of a single, version-scoped Launchpad Production V2 deployment. Every field is scoped * to one `chainId + factory`; a factory redeployment is a new deployment, never an in-place upgrade. * * Unlike V3, one factory now supports many quote tokens and launch configs (see * {@link LaunchpadEconomics}), so per-quote-token and per-config addresses do not exist here — the * factory is still the single per-chain entry point, it just no longer implies a fixed economics. * * Slot names track the contract repository's `deployment-manifest.json` `addresses` object key for * key (`contracts/production/release//deployment-manifest.json`). */ interface LaunchpadContracts { readonly factory: Address; /** CREATE2 deployer for the per-token pair of `LauncherToken` + `BondingCurve`. `factory.launchDeployer()`. */ readonly launchDeployer: Address; /** * Trusted forwarder for atomic creation, and the spender for both of its funding legs. * `factory.launchForwarder()`. * * Since 2026-09-07 this is the `HolderAwareLaunchForwarder`, which serves ordinary * `launchAndBuy` and the new `launchWithHolderFeeSharing` from one address. Rotating it is a * governed operation on the factory, so read it from the deployment record rather than pinning a * literal — {@link legacyLaunchForwarder} exists precisely because one rotation has happened * already. */ readonly launchForwarder: Address; /** * The forwarder this deployment rotated away from, kept only so historical receipts still decode. * * It can no longer reach `factory.launchTokenFor`, so it is not an alternative entry point — an * indexer should treat logs from it as history and never as a live source. */ readonly legacyLaunchForwarder?: Address; /** * Factory for the per-launch Holder Fee Sharing distributors. * * Maintained as a separate project behind the `IHolderDistributorFactory` adapter boundary, so * the SDK binds only to that interface. Verified against * `holderDistributorFactory.authorizedForwarder()`, which must name the same forwarder the launch * factory trusts — a one-sided rotation leaves exactly one of the two creation paths broken. */ readonly holderDistributorFactory?: Address; /** Owner/Controller-governed partner identities and their platform fee share. `factory.partnerRegistry()`. */ readonly partnerRegistry: Address; /** Permissionless-credit, self-serve-claim ledger every swept fee lands in. `factory.feeEscrow()`. */ readonly feeEscrow: Address; /** Five-year weighted-average vesting vault for the optional creator buyback. `factory.buybackVault()`. */ readonly buybackVault: Address; /** Uniswap V4 hook owning the graduated pool's swap fee split and partner epoch sweeps. `factory.memeHook()`. */ readonly memeHook: Address; /** Owns the `NotGraduated -> Swept -> PoolCreated` state machine. `factory.graduationCoordinator()`. */ readonly graduationCoordinator: Address; /** Builds the V4 pool and mints the graduation position; invoked by the coordinator. `factory.graduationExecutor()`. */ readonly graduationExecutor: Address; /** Permanent owner of the graduation position NFT and of any locked excess token supply. */ readonly launchLocker: Address; /** Deploys one `EmergencyDistributor` per launch via CREATE2. `factory.emergencyDistributorFactory()`. */ readonly emergencyDistributorFactory: Address; /** * Terminal owner of assets no distributor can pay out. Verified against * `emergencyDistributorFactory.orphanedAssetsRecipient()`, which is where it actually lives — the * factory refuses to graduate at all while it is unset, so a deployment missing it is broken * rather than merely incomplete. */ readonly orphanedAssetsVault: Address; /** Uniswap V4 singleton. Verified against `MemeHook.poolManager()`. */ readonly v4PoolManager: Address; readonly v4PositionManager: Address; readonly permit2: Address; } /** * One quote token a factory accepts, plus the curve economics it graduates against. Distinct from * V3, where a factory fixed exactly one quote token: here `approvedQuoteTokens`/`quoteTokenEconomics` * on the factory hold an arbitrary set, and `LaunchpadEconomics.quoteTokens` pins the ones this SDK * deployment knows about. A quote token absent from this list can still be approved on chain; the * SDK simply cannot quote or validate launches against it until the deployment record is updated. */ interface LaunchpadQuoteToken { readonly address: Address; /** Display symbol only; never used for equality checks. */ readonly symbol: string; /** `factory.quoteTokenEconomics(address).decimals`. */ readonly decimals: number; /** Virtual quote reserve added to `trackedQuote` for pricing. `quoteTokenEconomics(address).phantomQuote`. */ readonly phantomQuote: bigint; /** Net quote reserve at which a curve against this quote token graduates. `.graduationThreshold`. */ readonly graduationThreshold: bigint; /** `factory.approvedQuoteTokens(address)` at the time this record was pinned; re-checked live by `verify`. */ readonly approved: boolean; /** Manifest-only annotation (e.g. tUSDG); the contract has no concept of "test" quote tokens. */ readonly testOnly?: boolean; } /** * One template a creator can launch against: total supply, curve fee, and the graduation pool's * Uniswap V4 fee tier and tick spacing. `factory.launchConfig(id)`; `id` is the array index * `factory.validateAndResolve` and `CreateTokenParams.launchConfigId` both key off. */ interface LaunchpadLaunchConfig { readonly id: bigint; readonly supply: bigint; readonly curveFeeBps: bigint; readonly poolFee: number; readonly tickSpacing: number; readonly enabled: boolean; } /** * Governance-owned split of platform fee revenue and the creator buyback carve-out. * `factory.feePolicy()`. Mutable on chain (`setFeePolicy`) without a redeployment, so * {@link verifyLaunchpadDeployment} re-reads it live rather than trusting only the pinned copy — * the pinned copy exists so pure math needs no RPC round trip for the common case. */ interface LaunchpadFeePolicy { readonly protocolFeeRecipient: Address; readonly protocolFeeShareBps: number; /** Share of the *creator* fee bucket redirected to the buyback vault when a launch opts in. Field name tracks the contract's `buybackBurnBps`, despite the tokens being vested, not burned. */ readonly buybackBurnBps: number; readonly hookFeeBps: number; readonly maxInternalPriceImpactBps: number; } /** Default and ceiling partner share of the platform fee bucket. `partnerRegistry.partnerPolicy()`. */ interface LaunchpadPartnerPolicy { readonly defaultPartnerShareOfPlatformBps: number; readonly maxPartnerShareOfPlatformBps: number; } /** Seconds-based snipe tax decay. `factory.snipeTaxConfig()`; see `SnipeTax.sol` for the shift formula. */ interface LaunchpadSnipeTaxConfig { readonly startBps: number; readonly durationSeconds: number; } /** * Every deployment-scoped economics value the SDK needs, pinned from the deployment manifest. * * V3 fixed one quote token and one set of curve constants per factory; Production V2 factors * economics into three independently governed layers instead — quote tokens, launch configs, and a * single current fee policy — which a launch combines at creation time into an immutable snapshot * (`BondingCurve.feePolicySnapshot()`). This type mirrors the *current* layers, not any one launch's * frozen snapshot. * * Deliberately **absent**: `partnerPolicy` and `feePolicy` share bps are governance state a launch * only snapshots at creation — later governance changes do not retroactively apply to existing * curves, and the *default* partner share is even less binding since `createPartner` can set an * arbitrary share up to the max. They are pinned here anyway (unlike V3's referrer share) because * every currently-open action in this deployment's known lifecycle needs a value to validate new * launches against; `verify` re-reads both live. */ interface LaunchpadEconomics { readonly quoteTokens: readonly LaunchpadQuoteToken[]; readonly launchConfigs: readonly LaunchpadLaunchConfig[]; readonly feePolicy: LaunchpadFeePolicy; readonly partnerPolicy: LaunchpadPartnerPolicy; readonly snipeTax: LaunchpadSnipeTaxConfig; /** Flat fee a creator pays to launch, in `launchFeeToken` raw units. `factory.launchFee()`; currently `0`. */ readonly launchFeeRaw: bigint; /** `factory.launchFeeToken()`. Independent of `quoteTokens` — a launch can charge its fee in a token it will never trade against. */ readonly launchFeeToken: Address; /** Ceiling on a creator's atomic first buy, in bps of the launch config's `supply`. `factory.maxCreatorInitialBuyBps()`. */ readonly maxCreatorInitialBuyBps: number; /** Ceiling a creator's `creatorTaxBps` choice at launch may not exceed. `factory.maxCreatorTaxBps()`. */ readonly maxCreatorTaxBps: number; } /** * A Launchpad protocol deployment traceable to an exact contract revision. The runtime code hash * and the source/artifact commits let {@link verifyLaunchpadDeployment} prove the registered * addresses match on-chain state before any read or write is trusted. */ interface LaunchpadDeployment { readonly chainId: number; readonly contractVersion: string; readonly contracts: LaunchpadContracts; readonly economics: LaunchpadEconomics; readonly deploymentBlock: bigint; /** * Commit the bundled ABI artifacts were exported at. * * Distinct from {@link LaunchpadDeployment.sourceCommit} on purpose — the ABI generator can be * rerun against a later commit than the one described by an unrelated economics change, though in * practice the two are usually the same commit for this deployment. */ readonly artifactCommit: string; /** Commit of the Solidity sources the deployed bytecode was built from. */ readonly sourceCommit: string; readonly factoryRuntimeCodeHash: Hex; } type LaunchpadDeploymentRegistry = Readonly>; /** * Raised when supplied deployment material fails structural validation. Mirrors the plain-`Error` * shape of `InvalidLendingDomainError`; chain resolution reuses the shared `UnsupportedChainError` * instead. */ declare class InvalidLaunchpadDeploymentError extends Error { readonly field: string; constructor(field: string, message: string); } /** Validates, normalizes, and deep-freezes a caller-supplied Launchpad deployment. */ declare function defineLaunchpadDeployment(input: LaunchpadDeployment): Readonly; /** * Validates and freezes a chainId-keyed deployment registry, rejecting any entry whose key does * not match its own `chainId`. */ declare function defineLaunchpadDeploymentRegistry(input: Readonly>): LaunchpadDeploymentRegistry; /** * Built-in registry of production Launchpad deployments. It stays empty until a deployment has * passed RPC bytecode and binding verification; testnet material is exported separately as an * explicitly named development configuration. */ declare const launchpadDeploymentRegistry: LaunchpadDeploymentRegistry; /** Resolves a verified deployment or throws {@link UnsupportedChainError}. */ declare function resolveLaunchpadDeployment(registry: LaunchpadDeploymentRegistry, chainId: number): Readonly; /** Looks up a pinned quote token by address within a deployment's economics, or `undefined`. */ declare function findLaunchpadQuoteToken(economics: Readonly, quoteToken: Address): Readonly | undefined; /** Looks up a pinned launch config by id within a deployment's economics, or `undefined`. */ declare function findLaunchpadLaunchConfig(economics: Readonly, launchConfigId: bigint): Readonly | undefined; /** * Block selector threaded through every read so a page can pin token state, quotes, balances, and * allowances to one block instead of stitching together values from different heights. */ interface LaunchpadReadOptions { readonly blockNumber?: bigint; readonly blockTag?: BlockTag; } /** Public-client scope for a single verified deployment. */ interface LaunchpadActionContext { readonly publicClient: PublicClient; readonly deployment: LaunchpadDeployment; } /** Adds the signer required for write paths. Chain agreement is re-checked at call time. */ interface LaunchpadWriteActionContext extends LaunchpadActionContext { readonly walletClient: WalletClient; } /** Chain-scoped ERC-20 asset reference. */ interface LaunchpadAssetRef { readonly address: Address; } /** * `GraduationStatus` (`NotGraduated=0`, `Swept=1`, `PoolCreated=2`, `EmergencyExited=3`), named so * consumers never depend on the raw enum ordering. * * Replaces V3's five-phase `LaunchpadPhase`. Two differences matter. `swept` is a real, resumable * intermediate state — the curve's assets have left it but the V4 pool does not exist yet, and * `createGraduatedPool` can be retried from there — where V3's `migrating` was a single all-or- * nothing attempt. And there is no `invalid`: a token this factory did not launch has no record at * all, so `isLaunchpadToken` answers that question instead of a phase value. */ type LaunchpadGraduationStatus = "notGraduated" | "swept" | "poolCreated" | "emergencyExited"; /** * `LaunchedTokenRecord`: the immutable economics a launch was created with, plus the two mutable * fields the factory keeps in sync (`creatorFeeRecipient`, `buybackEnabled`). * * Everything else here is frozen at creation. Later governance changes to `FeePolicy`, * `LaunchConfig` or the quote token's economics do **not** retroactively apply — which is exactly * why the record stores its own copies rather than pointing at the current templates. */ interface LaunchpadLaunchRecord { readonly token: Address; /** The token's own `BondingCurve`. Every trade, quote and fee read goes here, not to the factory. */ readonly curve: Address; /** Fixed at creation and never transferable; distinct from {@link creatorFeeRecipient}. */ readonly originalCreator: Address; /** Current recipient of creator fees. Transferable by the creator, and overridable by governance on a delay. */ readonly creatorFeeRecipient: Address; readonly quoteToken: Address; readonly launchConfigId: bigint; /** `EconomicsHash.hash` of the ten economics fields this launch was created against. */ readonly economicsHash: Hex; readonly buybackEnabled: boolean; readonly creatorTaxBps: number; readonly hookFeeBps: number; readonly protocolFeeShareBps: number; readonly buybackBurnBps: number; readonly maxInternalPriceImpactBps: number; readonly tickSpacing: number; readonly phantomQuote: bigint; readonly protocolFeeRecipient: Address; } /** * A curve's live pricing state, read together at one block. * * `trackedTokens`/`trackedQuote` are the curve's own accounting, not balances: a forced ERC-20 * transfer into the curve raises its balance without touching either, and is therefore never * priced against. */ interface LaunchpadCurveState { readonly curve: Address; /** `initialSupply`: the full mint, fixed at creation. */ readonly initialSupply: bigint; readonly phantomQuote: bigint; /** The curve's own immutable graduation threshold, which fixes `reservedTokens`. */ readonly graduationThreshold: bigint; /** * The curve's own immutable fee constants. Carried here so the state is self-sufficient for * `simulateLaunchpadBuyExactIn`/`simulateLaunchpadSellExactIn` — pricing a trade otherwise needs * three more round trips for values that can never change. */ readonly curveFeeBps: number; readonly creatorTaxBps: number; /** `snipeTaxConfigSnapshot()`, frozen at creation — not the factory's current global setting. */ readonly snipeTax: { readonly startBps: number; readonly durationSeconds: number; }; readonly trackedTokens: bigint; readonly trackedQuote: bigint; readonly quoteFeeBalance: bigint; readonly creatorTaxBalance: bigint; /** Derived: `phantomQuote + trackedQuote - quoteFeeBalance - creatorTaxBalance`. */ readonly quoteReserve: bigint; /** Derived: `trackedTokens`. */ readonly tokenReserve: bigint; /** Tokens still purchasable before the Token-side graduation boundary. */ readonly sellableTokens: bigint; readonly reservedTokens: bigint; /** `true` once `sellableTokens` reaches zero; trading closes and graduation opens. */ readonly graduationReady: boolean; readonly graduated: boolean; /** `block.timestamp` of the curve's construction, the snipe tax decay origin. */ readonly launchedAt: bigint; } /** Fees a curve has accrued but not yet swept out to {@link LaunchpadFeeEscrowBalance}. */ interface LaunchpadCurvePendingFees { readonly protocol: bigint; /** Includes `creatorTax`; the contract sums both into one pending bucket. */ readonly creator: bigint; /** The creator-tax portion of {@link creator}, tracked separately for reserve accounting. */ readonly creatorTax: bigint; readonly buyback: bigint; } /** `GraduationRecord`, as reported by both the factory and the coordinator. */ interface LaunchpadGraduationRecord { readonly status: LaunchpadGraduationStatus; /** `0` until the curve has been swept. */ readonly sweptAt: bigint; /** Tokens handed to the executor at sweep time. */ readonly tokenAmount: bigint; /** Quote handed to the executor at sweep time, net of unswept fee liabilities. */ readonly quoteAmount: bigint; /** The V4 position NFT id, non-zero only once `poolCreated`. */ readonly positionId: bigint; } /** Chain-scoped view combining a launch's record, its curve state, and its graduation status. */ interface LaunchpadTokenState { readonly id: LaunchpadTokenId; readonly record: LaunchpadLaunchRecord; readonly curveState: LaunchpadCurveState; readonly graduation: LaunchpadGraduationRecord; } /** * A curve buy quote. `quoteSpent` can be below the offered amount when the buy reaches the * graduation boundary, in which case the difference is refunded atomically — approvals and UI must * follow `quoteSpent`, never the user's input. */ interface BuyQuote { readonly tokenOut: bigint; readonly quoteSpent: bigint; readonly refund: bigint; /** Quote reaching the curve reserve, after all three fee components. */ readonly netQuoteIn: bigint; readonly baseFee: bigint; readonly snipeTax: bigint; readonly creatorTax: bigint; readonly totalFee: bigint; /** Snipe tax rate applied, resolved for the **token recipient**, not the payer. */ readonly snipeTaxBps: number; /** * The buy was truncated to the curve's remaining sellable supply and the rest refunded. * * Also the signal that this trade closes the curve: RC2 graduates the launch in the same * transaction, so re-read the graduation status afterwards instead of assuming `notGraduated`. */ readonly isPartialFill: boolean; } /** A curve sell quote. `netQuoteOut` is what the seller receives; the gross overstates it by the fee. */ interface SellQuote { readonly tokenIn: bigint; readonly grossQuoteOut: bigint; readonly netQuoteOut: bigint; readonly baseFee: bigint; readonly creatorTax: bigint; readonly totalFee: bigint; } /** Slippage tolerance in basis points. Validated against a hard 50% ceiling. */ interface Slippage { readonly bps: number; } /** * Why a curve trade is currently rejected, or `undefined` when trading is available. * * V2 has no factory-wide pause and no creation-block window, so V3's `curvePaused` and `sameBlock` * are both gone. `graduationReady` is the new one: the curve has sold through to its reserved floor * and closed to trading, but nobody has called `graduate` yet. * * Deliberately narrower than `_requireTradingOpen`'s full set of gates. Its other two — * `CurveTokenNotInitialized` and `LaunchTaxExemptionsNotInitialized` — are unreachable for anything * an SDK caller can observe, because both are set inside `createToken` in the same transaction that * deploys the curve; a curve resolved through `curveFor` at any block boundary always has them. * Its deadline check is per-call rather than per-state, so it belongs to the trade, not here. * Listing reasons that can never occur would imply states a UI must handle and does not exist. */ type LaunchpadTradeBlockedReason = "graduationReady" | "graduated" | "emergencyExited"; /** Everything a UI needs to render trade availability, derived from one observed block. */ interface LaunchpadTradeAvailability { readonly status: LaunchpadGraduationStatus; readonly canBuy: boolean; readonly canSell: boolean; /** Curve fee plus creator tax; the snipe tax is per-recipient and is quoted separately. */ readonly baseFeeBps: number; /** Snipe tax right now for a non-exempt recipient. `0` once the window has elapsed. */ readonly snipeTaxBps: number; readonly blockNumber: bigint; /** Chain timestamp the snipe tax was resolved at. */ readonly timestamp: bigint; readonly blockedReason?: LaunchpadTradeBlockedReason; } /** * Graduation progress measured on the **Token** side, matching the contract's own boundary. * * V3 measured against a quote target, which a single large buy could overshoot. V2's boundary is * `sellableTokens == 0`, so progress is the fraction of initially-sellable supply already sold and * can never exceed 100%. */ interface LaunchpadGraduationProgress { readonly progressBps: number; readonly soldTokens: bigint; readonly initialSellableTokens: bigint; readonly sellableTokens: bigint; } /** A CREATE2-predicted launch address pair, from `LaunchDeployer.predictLaunchAddresses`. */ interface PredictedLaunchpadToken { readonly token: Address; readonly curve: Address; readonly creator: Address; /** The `salt` the prediction is bound to. A salt is single-use per creator. */ readonly salt: Hex; } /** On-chain name, symbol, and decimals for a token, read together at one block. */ interface LaunchpadErc20Metadata { readonly address: Address; readonly name: string; readonly symbol: string; readonly decimals: number; } /** `LauncherToken`'s permanently stored, structured token info. */ interface LaunchpadTokenInfo { readonly name: string; readonly symbol: string; readonly logo: string; readonly description: string; readonly socials: { readonly twitter: string; readonly telegram: string; readonly discord: string; readonly website: string; readonly farcaster: string; }; readonly deployer: Address; readonly curve: Address; /** `TokenInfo.hash` over the fields above, as the token itself reports it. */ readonly tokenInfoHash: Hex; } /** `PartnerRegistry.PartnerConfig`. */ interface LaunchpadPartnerConfig { readonly partnerId: Hex; readonly name: string; /** Manages the recipient, via a propose/accept handover. Cannot change the share. */ readonly controller: Address; /** The only address that may claim this partner's escrow balance. */ readonly recipient: Address; /** Cut of the platform fee bucket, read live per trade rather than snapshotted per token. */ readonly shareOfPlatformBps: number; /** Permanently `true` once created; ids are never deleted or recycled. */ readonly exists: boolean; /** While `false`, new trades accrue nothing and existing balances are frozen, not forfeited. */ readonly enabled: boolean; } /** `PartnerRegistry.partnerPolicy()`. */ interface LaunchpadPartnerPolicySnapshot { readonly defaultPartnerShareOfPlatformBps: number; /** Can only be raised once a partner exists, never lowered. */ readonly maxPartnerShareOfPlatformBps: number; } /** A claimable `FeeEscrow` balance, keyed the way the escrow itself keys it. */ interface LaunchpadFeeEscrowBalance { readonly asset: Address; readonly amount: bigint; /** * Escrow balances are keyed by `(recipient, asset)` — **never** by launch token. A recipient used * across several launches accumulates one indistinguishable balance per asset, and the chain * cannot attribute it back to individual launches. */ readonly recipient: Address; } /** A partner's claimable `FeeEscrow` balance, keyed by `(partnerId, asset)`. */ interface LaunchpadPartnerEscrowBalance { readonly partnerId: Hex; readonly asset: Address; readonly amount: bigint; } /** `BuybackVault.vest(token)`: the five-year weighted-average vesting clock for one launch. */ interface LaunchpadBuybackVest { readonly token: Address; readonly totalLocked: bigint; readonly totalReleased: bigint; readonly vestingStart: bigint; readonly vestedUnreleased: bigint; readonly unvestedAmount: bigint; readonly lastUpdate: bigint; /** Moves later on every new deposit: the clock is one weighted average, not per-tranche. */ readonly vestingEnd: bigint; readonly creatorRecipient: Address; readonly protocolRecipient: Address; readonly protocolFeeShareBps: number; } /** An `EmergencyDistributor`'s redemption state. */ interface LaunchpadEmergencyExitState { readonly distributor: Address; readonly launchToken: Address; readonly quoteToken: Address; readonly activated: boolean; /** Redeemable supply recorded at activation, for reference only. */ readonly initialRedeemableSupply: bigint; /** * Quote still held for redemption. The numerator of every payout; the denominator is the token's * **live** `totalSupply()`, re-read on each redemption rather than snapshotted, so a holder who * burns without redeeming increases everyone else's share. */ readonly remainingQuote: bigint; } /** Canonical identifier for a Launchpad token. Addresses alone are not cross-chain identifiers. */ interface LaunchpadTokenId { readonly chainId: number; readonly address: Address; } /** * Product features an integrator can switch off per chain. Every member gates a real write path; * a capability that gates nothing is worse than absent, because it reads as a working switch. * * Deliberately **not** capabilities: graduation, fee claiming, buyback release and emergency * redemption. All four are permissionless recoveries of value that already belongs to someone else * — a graduated launch's liquidity, accrued fees, vested buyback tokens, a holder's share of a * failed launch — so a product switch must not be able to strand them. * * `referral` is gone with V3's referrer system. `partnerAttribution` replaces nothing: it gates * only whether this integrator tags its own trades with a partner id, never whether a trade can * happen. */ type LaunchpadCapability = "create" | "bondingTrade" | "partnerAttribution"; interface LaunchpadQuoteTokenConfig { readonly address: Address; readonly decimals: number; readonly symbol: string; } /** * Per-chain network and product metadata for the ABI-neutral adapter client. `deployment` is the * same verified {@link LaunchpadDeployment} the typed `LaunchpadFactoryClient` uses — there is no * separate, looser address shape here. This keeps the migrator and locker as distinct, named module * slots instead of collapsing them into one ambiguous "router". */ interface LaunchpadChainConfig { readonly slug: string; readonly chainId: number; readonly family: "evm"; readonly nativeCurrency: { readonly symbol: string; readonly decimals: number; }; readonly rpcUrls: readonly string[]; readonly explorerUrl: string; readonly apiBaseUrl: string; readonly realtimeUrl: string; readonly deployment: LaunchpadDeployment; readonly quoteTokens: readonly LaunchpadQuoteTokenConfig[]; readonly capabilities: Readonly>; readonly confirmations: number; } type LaunchpadChainRegistry = Readonly>; /** * ABI-neutral request passed to a contract adapter. The operation and argument shape become typed * only after the Launchpad contracts are delivered and their public interface is frozen. */ interface LaunchpadReadRequest { readonly operation: string; readonly args?: unknown; } interface LaunchpadWriteRequest extends LaunchpadReadRequest { readonly requiredCapability: LaunchpadCapability; } interface LaunchpadReadContext { readonly chain: LaunchpadChainConfig; readonly publicClient: PublicClient; } interface LaunchpadWriteContext extends LaunchpadReadContext { readonly walletClient: WalletClient; } /** Adapter boundary for generated ABI bindings and protocol-specific actions. */ interface LaunchpadContractAdapter { read(context: LaunchpadReadContext, request: LaunchpadReadRequest): Promise; write(context: LaunchpadWriteContext, request: LaunchpadWriteRequest): Promise; } type LaunchpadAdapterRegistry = Readonly>; interface LaunchpadClientConfig { readonly publicClient: PublicClient; readonly walletClient?: WalletClient; readonly chains: LaunchpadChainRegistry; readonly adapters?: LaunchpadAdapterRegistry; } interface LaunchpadClient { readonly publicClient: PublicClient; readonly walletClient?: WalletClient; getChain(chainId?: number): LaunchpadChainConfig; getAdapter(chainId?: number): LaunchpadContractAdapter; read(request: LaunchpadReadRequest, chainId?: number): Promise; write(request: LaunchpadWriteRequest, chainId?: number): Promise; } /** Allowance status for one asset/spender pair, resolved at a single block. */ interface LaunchpadApprovalStatus { readonly asset: Address; readonly owner: Address; readonly spender: Address; readonly allowance: bigint; readonly requiredAmount: bigint; readonly sufficient: boolean; /** Exactly the shortfall, so a caller can approve the precise amount still needed. */ readonly missingAmount: bigint; } /** * Resolves whether an exact-amount approval is still required. * * The spender for creation, buy, and sell is always the factory — never a pool and never a future * DEX router. For a buy, `requiredAmount` should be the quote's `quoteSpent` rather than the user's * typed input, because a graduating buy spends less than requested. */ declare function getLaunchpadApprovalStatus(context: LaunchpadActionContext, input: { readonly asset: Address; readonly owner: Address; readonly requiredAmount: bigint; readonly spender?: Address; }, options?: LaunchpadReadOptions): Promise; declare const preparedLaunchpadTransactionBrand: unique symbol; interface PreparedLaunchpadTransactionContext { readonly chainId: number; readonly account: Address; readonly factory: Address; } interface PreparedLaunchpadTransaction { readonly [preparedLaunchpadTransactionBrand]: true; /** Frozen inspection copy; send uses the store's separate canonical simulation request. */ readonly request: Readonly>; readonly preview: Preview; readonly context: PreparedLaunchpadTransactionContext; } declare function toPreparedLaunchpadTransaction(request: Record, preview: Preview, context: PreparedLaunchpadTransactionContext): PreparedLaunchpadTransaction; declare function launchpadPreparedContext(context: LaunchpadWriteActionContext, account: Account): PreparedLaunchpadTransactionContext; declare function sendPreparedLaunchpadTransaction(context: LaunchpadWriteActionContext, prepared: PreparedLaunchpadTransaction): Promise; /** * Reads a launch's buyback vesting state. * * The clock is a single weighted average over everything ever locked, not a set of per-deposit * tranches: each new deposit pushes `vestingEnd` further out for the whole balance. So a launch * with steady buyback flow never fully vests while the flow continues, and `vestingEnd` is a * moving target rather than a date to count down to. */ declare function getLaunchpadBuybackVest(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** Tokens releasable from the vault right now. */ declare function getLaunchpadBuybackReleasable(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** The vault's fixed vesting horizon for a fresh deposit. */ declare function getLaunchpadBuybackVestingDuration(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; interface BuybackReleasePreview { readonly token: Address; readonly releasable: bigint; readonly creatorRecipient: Address; readonly protocolRecipient: Address; } /** * Prepares a release of vested buyback tokens. * * The release is split between the creator recipient and the protocol recipient by the launch's * snapshotted `protocolFeeShareBps`, and it pays both regardless of who calls — the caller is only * the trigger, never the beneficiary. */ declare function prepareLaunchpadBuybackRelease(context: LaunchpadWriteActionContext, token: Address): Promise>; /** * Prepares a change to a launch's buyback switch. * * The permission is deliberately asymmetric and enforced in the factory, not just the UI: the * current creator fee recipient may turn buyback **on or off**, while the protocol owner may only * turn it **off**. Either way the change applies only to fees produced afterwards — anything * already earmarked, pending, mid-sweep, or in the vault is never retroactively rerouted. */ declare function prepareLaunchpadSetBuybackEnabled(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly enabled: boolean; }): Promise>; /** * Resolves the launch config and quote-token economics a creation would use, straight from the * factory. * * **Two arguments, not three.** `PRODUCTION_FRONTEND_INTEGRATION.md` documents this as * `validateAndResolve(quoteToken, launchConfigId, creatorTaxBps)`, but neither the ABI nor * `LaunchConfiguration.sol` has a third parameter — the creator tax is validated separately by * `_validateCreatorTaxCombination`. Calling it the documented way fails to encode. * * Reverts when the pairing is unusable (quote token unapproved, economics unconfigured, config * missing or disabled), so it doubles as the pre-flight check for a creation form. */ declare function validateAndResolveLaunchConfig(context: LaunchpadActionContext, input: { readonly quoteToken: Address; readonly launchConfigId: bigint; }, options?: LaunchpadReadOptions): Promise<{ readonly launchConfig: Omit; readonly quoteTokenEconomics: Pick; }>; /** Reads one launch config template by id. */ declare function getLaunchpadLaunchConfig(context: LaunchpadActionContext, launchConfigId: bigint, options?: LaunchpadReadOptions): Promise; /** How many launch config templates exist. Ids are the indices `[0, count)`. */ declare function getLaunchpadLaunchConfigCount(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** Reads every launch config template, in id order. */ declare function getLaunchpadLaunchConfigs(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** Reads a quote token's approval flag and curve economics. */ declare function getLaunchpadQuoteTokenEconomics(context: LaunchpadActionContext, quoteToken: Address, options?: LaunchpadReadOptions): Promise<{ readonly approved: boolean; readonly phantomQuote: bigint; readonly graduationThreshold: bigint; readonly decimals: number; }>; /** Reads the factory's current fee policy. Mutable governance state, not a per-launch snapshot. */ declare function getLaunchpadFeePolicy(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** Reads the factory's current snipe tax configuration for **new** launches. */ declare function getLaunchpadSnipeTaxConfig(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise<{ readonly startBps: number; readonly durationSeconds: number; }>; /** Whether an account may launch right now, accounting for the denylist, gate and whitelist. */ declare function canLaunchpadCreatorLaunch(context: LaunchpadActionContext, creator: Address, options?: LaunchpadReadOptions): Promise; /** The three inputs behind {@link canLaunchpadCreatorLaunch}, for explaining a refusal. */ interface LaunchpadLaunchGate { readonly canLaunch: boolean; readonly launchEnabled: boolean; readonly whitelisted: boolean; readonly denied: boolean; } /** * Reads the full launch gate for one creator. * * The denylist takes precedence over everything: a denied creator cannot launch even with public * launch enabled and even if also whitelisted. */ declare function getLaunchpadLaunchGate(context: LaunchpadActionContext, creator: Address, options?: LaunchpadReadOptions): Promise; /** Whether a creator has already consumed a CREATE2 salt. Salts are single-use per creator. */ declare function isLaunchpadSaltUsed(context: LaunchpadActionContext, input: { readonly creator: Address; readonly salt: Hex; }, options?: LaunchpadReadOptions): Promise; /** A pending governance override of a launch's creator fee recipient. */ interface LaunchpadPendingCreatorRecipientChange { readonly proposedRecipient: Address; /** Executable from this timestamp (three days after proposal). */ readonly effectiveAt: bigint; /** Expires here (three days after {@link effectiveAt}); after this it must be proposed again. */ readonly expiresAt: bigint; readonly pending: boolean; } /** Reads any pending creator-fee-recipient override for a launch. */ declare function getLaunchpadPendingCreatorRecipientChange(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** Curve progress for a token screen, resolved at one pinned block. */ interface LaunchpadCurveProgress extends LaunchpadGraduationProgress { readonly blockNumber: bigint; readonly status: LaunchpadGraduationStatus; } /** * Reads how far a curve is from graduating. * * Measured on the **Token** side — sold against initially-sellable supply — because that is the * contract's own boundary. V3 measured a quote reserve against a target, which one large buy could * overshoot; this saturates at exactly 100% and reaches it at the same instant the curve closes. */ declare function getLaunchpadCurveProgress(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** * The curve's marginal price, as raw quote units per one whole (1e18) token. * * A marginal price, never an executable one: any real trade moves along the curve, so a * `minTokenOut` must come from a quote rather than from multiplying by this. The contracts expose * no spot-price getter of their own — this is derived from `pricingReserves`. */ declare function launchpadSpotPrice(curveState: LaunchpadCurveState): bigint; /** Net quote required to buy exactly `tokenOut`, computed locally from curve state. */ declare function launchpadNetRequiredToBuy(curveState: LaunchpadCurveState, tokenOut: bigint): bigint; /** Tokens `netQuoteIn` buys, before the sellable cap, computed locally from curve state. */ declare function launchpadTokensForNetQuote(curveState: LaunchpadCurveState, netQuoteIn: bigint): bigint; /** * The distributor address for a launch, whether or not it has been deployed yet. * * Deployment is CREATE2-deterministic per `(launchToken, quoteToken)`, so the address can be shown * before an exit is triggered. `deployed` distinguishes a prediction from a live contract. */ declare function getLaunchpadEmergencyDistributorAddress(context: LaunchpadActionContext, input: { readonly launchToken: Address; readonly quoteToken: Address; }, options?: LaunchpadReadOptions): Promise<{ readonly distributor: Address; readonly deployed: boolean; }>; /** Reads a deployed distributor's redemption state. */ declare function getLaunchpadEmergencyExitState(context: LaunchpadActionContext, distributor: Address, options?: LaunchpadReadOptions): Promise; /** What a redemption would pay out, quoted against the token's live total supply. */ interface EmergencyRedeemQuote { readonly tokenIn: bigint; readonly quoteOut: bigint; /** The live `totalSupply()` used as the denominator; **not** a snapshot. */ readonly supply: bigint; readonly remainingQuote: bigint; /** True when `tokenIn` is the entire remaining supply, which sweeps the whole remaining quote. */ readonly isFinalRedemption: boolean; } /** * Quotes an emergency redemption. * * The denominator is the launch token's **live** `totalSupply()`, re-read on every redemption * rather than frozen at activation — a V3 exit divided by a fixed snapshot instead. The practical * consequence is that a holder who burns their tokens without redeeming does not forfeit their * share into a void: it is redistributed across everyone who remains, so each surviving holder's * payout per token rises. Quotes therefore drift with other people's behaviour and should be * re-read immediately before submitting. */ declare function quoteLaunchpadEmergencyRedeem(context: LaunchpadActionContext, input: { readonly distributor: Address; readonly tokenIn: bigint; }, options?: LaunchpadReadOptions): Promise; /** Prepares an emergency redemption, burning `tokenIn` for a pro-rata share of the remaining quote. */ declare function prepareLaunchpadEmergencyRedeem(context: LaunchpadWriteActionContext, input: { readonly distributor: Address; readonly tokenIn: bigint; readonly recipient?: Address; }): Promise>; /** `GraduationCoordinator.EMERGENCY_EXIT_DELAY`: seven days, measured from the sweep. */ declare const LAUNCHPAD_EMERGENCY_EXIT_DELAY_SECONDS: bigint; /** * When a launch's emergency exit becomes callable, or `undefined` while it cannot. * * The exit is narrower than "a stuck launch": it requires the launch to already be `swept`, and the * clock runs from `sweptAt`, not from creation. It exists for the one gap the two-step graduation * opens — assets have left the curve but `createGraduatedPool` keeps failing — so a launch still * trading on its curve has nothing to exit from. */ declare function launchpadEmergencyExitAvailableAt(graduation: Pick): bigint | undefined; /** * Prepares `emergencyExit`, which is **owner-only** — unlike both graduation steps. * * Worth stating plainly, because the surrounding lifecycle is permissionless and the name suggests * an escape hatch anyone can pull: `LaunchFactory.emergencyExit` is `onlyOwner`. A stranded holder * cannot trigger their own exit; they can only redeem once governance has. Verified on a fork — * the same call from an ordinary account reverts. * * Requires the launch to be in `swept` and seven days to have passed since `sweptAt` — see * {@link launchpadEmergencyExitAvailableAt}. There is one path and one delay: V3's guarded * one-hour fast track no longer exists. */ declare function prepareLaunchpadEmergencyExit(context: LaunchpadWriteActionContext, token: Address): Promise>; /** * Prepares `syncDonatedTokens`, folding tokens sent directly to the distributor into the burn * accounting. Permissionless housekeeping — it pays the caller nothing. */ declare function prepareLaunchpadSyncDonatedTokens(context: LaunchpadWriteActionContext, distributor: Address): Promise>; /** * Prepares `releaseOrphanedQuote`, sweeping quote left behind once no redeemable supply remains, * to the factory's configured orphaned-assets recipient. Permissionless. */ declare function prepareLaunchpadReleaseOrphanedQuote(context: LaunchpadWriteActionContext, distributor: Address): Promise>; /** * Reads a recipient's claimable balance for one asset. * * **The escrow keys balances by `(recipient, asset)` and nothing else.** It does not record which * launch a credit came from, so a recipient reused across several launches — a creator who has * launched more than one token, or a holder distributor serving several — accumulates one * indistinguishable pool per asset that the chain cannot attribute back. Anything needing * per-launch attribution has to reconstruct it off-chain from `CurveFeesSwept`/`FeeCredited` * events, or use a distinct recipient address per launch. */ declare function getLaunchpadClaimableBalance(context: LaunchpadActionContext, input: { readonly recipient: Address; readonly asset: Address; }, options?: LaunchpadReadOptions): Promise; /** Reads a partner's claimable balance, keyed by `(partnerId, asset)` rather than by recipient. */ declare function getLaunchpadPartnerClaimableBalance(context: LaunchpadActionContext, input: { readonly partnerId: Hex; readonly asset: Address; }, options?: LaunchpadReadOptions): Promise; /** What a claim will move. */ interface ClaimPreview { readonly asset: Address; readonly amount: bigint; readonly recipient: Address; readonly partnerId?: Hex; } /** * Prepares a claim of the caller's own escrow balance for one asset. * * Self-service: only the recipient can claim their own balance, and there is no "claim on behalf * of" path. Omit `amount` to sweep the whole balance. */ declare function prepareLaunchpadClaim(context: LaunchpadWriteActionContext, input: { readonly asset: Address; readonly amount?: bigint; }): Promise>; /** * Prepares a partner claim. * * Only the partner's **current** recipient in the registry may call this, and the balance stays * attached to the `partnerId` rather than to any address — so rotating the recipient hands the * entire unclaimed balance to the new one, and the old one immediately loses access. A disabled * partner cannot claim at all; the balance is frozen, not forfeited, and becomes claimable again * on re-enable. */ declare function prepareLaunchpadPartnerClaim(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly asset: Address; }): Promise>; /** Owner-only: add or remove a creator from the denylist, which outranks every other launch gate. */ declare function prepareLaunchpadSetDeniedCreator(context: LaunchpadWriteActionContext, input: { readonly creator: Address; readonly denied: boolean; }): Promise>>; /** Owner-only: allow a specific creator to launch while public launch is disabled. */ declare function prepareLaunchpadSetWhitelistedLauncher(context: LaunchpadWriteActionContext, input: { readonly creator: Address; readonly enabled: boolean; }): Promise>>; /** Owner-only: open or close public launch for everyone not on the denylist. */ declare function prepareLaunchpadSetLaunchEnabled(context: LaunchpadWriteActionContext, enabled: boolean): Promise>>; /** * Hands a launch's creator fee recipient to a new address, immediately. * * Callable by the **current** recipient, with no delay — the timelocked path is the governance * override below, which exists for the case where the recipient cannot or will not act. Moving the * recipient also moves the buyback on/off authority, since that permission follows the recipient * rather than the original creator. * * This applies to a Holder Fee Sharing launch too, and it is the reason such a launch must not be * described as irreversible. Nothing on chain pins the distributor in place: the current recipient * can transfer fees away from it, and governance can override it on the usual delay. What is * immutable is the registry entry — assets already inside the distributor stay there, and * `distributorForToken` keeps answering, but future fees follow the recipient. */ declare function prepareLaunchpadTransferCreatorFeeRecipient(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly newRecipient: Address; }): Promise>>; /** * Owner-only step one of the creator-recipient override: propose a replacement. * * Two windows follow, both three days. The proposal cannot execute until the first elapses, and it * expires once the second does — so an override left unexecuted for six days must be proposed * again rather than simply executed late. */ declare function prepareLaunchpadProposeCreatorFeeRecipientOverride(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly newRecipient: Address; }): Promise>>; /** Owner-only step two: execute a matured override, inside its three-day execution window. */ declare function prepareLaunchpadExecuteCreatorFeeRecipientOverride(context: LaunchpadWriteActionContext, token: Address): Promise>>; /** Owner-only: withdraw a pending override before it executes. */ declare function prepareLaunchpadCancelCreatorFeeRecipientOverride(context: LaunchpadWriteActionContext, token: Address): Promise>>; /** * Owner-only emergency settlement of a curve's recorded fee liabilities, paying recipients * directly instead of routing through the escrow. * * Settles only what is already recorded — it does not recompute or reallocate any share. */ declare function prepareLaunchpadRescueCurveFees(context: LaunchpadWriteActionContext, token: Address): Promise>>; /** * Owner-only emergency settlement of one partner's recorded liability on a curve. * * Requires the partner to be registered **and enabled**: a disabled partner's balance stays frozen * and cannot be rescued out, which is deliberate rather than an oversight. */ declare function prepareLaunchpadRescuePartnerFees(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly partnerId: Hex; }): Promise>>; /** * Owner-only recovery of a graduated pool's stuck hook fees, added in RC2. * * Distinct from {@link prepareLaunchpadRescueCurveFees}, which settles the pre-graduation curve: * this one settles the `MemeHook`'s pending protocol and creator balances for a pool whose ordinary * sweep cannot make progress. It is a governance path, not a keeper task — RC2's sweeps already * settle partially rather than reverting, so reaching for this in normal operation papers over a * problem instead of draining it. */ declare function prepareLaunchpadRescueHookFees(context: LaunchpadWriteActionContext, token: Address): Promise>>; /** * Owner-only recovery of one partner's hook fees, added in RC2. * * Three constraints are easy to get wrong, and all three revert as a bare `InvalidConfiguration`: * * - `epochId` must be the hook's **`currentEpoch`** — the one still accruing, not the one being * settled. This is not a rescue for a stuck settlement; it pulls a partner out of the epoch that * has yet to be swept and pays them directly, which also clears their `partnerActive` flag and * decrements `activePartnerCount` for that epoch. Read it from * `getLaunchpadPoolSweepState(...).currentEpoch`, never from `settlingEpochId`. * - `asset` must be the launch token or the pool's quote token; anything else reverts. * - The partner must be registered **and enabled**, and must actually be owed a non-zero amount. */ declare function prepareLaunchpadRescueHookPartnerFees(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly epochId: bigint; readonly partnerId: Hex; readonly asset: Address; }): Promise>>; /** Owner-only: adjust the snipe tax applied to **future** launches. Existing curves keep their snapshot. */ declare function prepareLaunchpadSetSnipeTax(context: LaunchpadWriteActionContext, input: { readonly startBps?: number; readonly durationSeconds?: number; }): Promise>> | Promise>>; /** Owner-only: create a partner. The id is derived from a monotonic nonce and returned by the call. */ declare function prepareLaunchpadCreatePartner(context: LaunchpadWriteActionContext, input: { readonly name: string; readonly controller: Address; readonly recipient: Address; }): Promise>>; /** Owner-only: change a partner's share of the platform fee bucket. */ declare function prepareLaunchpadSetPartnerShare(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly shareOfPlatformBps: number; }): Promise>>; /** * Owner-only: enable or disable a partner. * * Disabling stops future accrual and freezes claiming, but never reassigns or forfeits an existing * balance — it becomes claimable again on re-enable. It also clears any pending controller * handover. */ declare function prepareLaunchpadSetPartnerEnabled(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly enabled: boolean; }): Promise>>; /** Owner-only: rename a partner. Display only; the id remains the sole identity. */ declare function prepareLaunchpadSetPartnerName(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly name: string; }): Promise>>; /** Controller-only: point a partner's payouts at a new recipient. Moves the unclaimed balance with it. */ declare function prepareLaunchpadSetPartnerRecipient(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly recipient: Address; }): Promise>>; /** Controller-only step one of the controller handover. */ declare function prepareLaunchpadProposePartnerController(context: LaunchpadWriteActionContext, input: { readonly partnerId: Hex; readonly newController: Address; }): Promise>>; /** Step two: the proposed controller accepts. Blocked while the partner is disabled. */ declare function prepareLaunchpadAcceptPartnerController(context: LaunchpadWriteActionContext, partnerId: Hex): Promise>>; /** * Reads the graduation record from the coordinator rather than the factory. * * The two agree — the factory's `graduations` getter delegates — but the coordinator is where the * state machine and its events actually live, so an indexer following graduation must watch the * coordinator's address and not the factory's. */ declare function getLaunchpadGraduationFromCoordinator(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** The V4 pool id the hook assigned a graduated token, or `bytes32(0)` before the pool exists. */ declare function getLaunchpadPoolId(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise<`0x${string}`>; /** What the caller is about to advance, and where it will land. */ interface GraduationStepPreview { readonly token: Address; readonly step: "graduate" | "createGraduatedPool"; readonly statusBefore: LaunchpadGraduationRecord["status"]; } /** * Whether a first-step graduation failure should be treated as success. * * RC2 graduates automatically at the end of the buy that empties the curve, so between a keeper * reading `NotGraduated` and its own `graduate` landing, someone else's trade may already have done * the work. The revert that follows is `InvalidGraduationState`, which the SDK surfaces as a * {@link LaunchpadPhaseUnavailableError} — indistinguishable, from the error alone, from a genuine * "not ready yet". Resolve it by re-reading the status: `swept` or `poolCreated` means the intent * was satisfied and the keeper should neither alert nor retry step one. */ declare function launchpadGraduateIsIdempotentSuccess(status: LaunchpadGraduationRecord["status"]): boolean; /** * Prepares step one of graduation: sweeping the curve's assets to the executor. * * Permissionless — any address may call it once `sellableTokens` reaches zero, so a keeper, the * creator, or the last buyer can all drive it. On success the launch moves to `swept`, which is a * resting state, not a transient one: step two can be attempted later, repeatedly, without * re-running this. * * Refuses up front when the launch has already advanced, rather than building a transaction that is * certain to revert. Under RC2 that is the common case, not a rare race: a buy that clears the last * sellable token graduates the launch inside the same transaction, so a launch can move from * `NotGraduated` to `Swept` with nobody having called this at all. The thrown * {@link LaunchpadPhaseUnavailableError} carries the observed status; see * {@link launchpadGraduateIsIdempotentSuccess} for the keeper-side reading of it. */ declare function prepareLaunchpadGraduate(context: LaunchpadWriteActionContext, token: Address): Promise>; /** * Prepares step two: creating the Uniswap V4 pool and minting the graduation position. * * Also permissionless, and **retryable** — this is the substantive difference from V3's * all-or-nothing `migrate`. A failure here leaves the launch at `swept` with its assets safe in the * executor rather than stranding them, so the call can simply be made again once whatever blocked * it (a seed feasibility check, a transient pool condition) clears. */ declare function prepareLaunchpadCreateGraduatedPool(context: LaunchpadWriteActionContext, token: Address): Promise>; /** One published epoch of holder revenue, as `HolderDistributor.getEpoch` returns it. */ interface LaunchpadHolderEpoch { readonly epochId: bigint; /** Merkle root over `(account, quoteAmount, coinAmount)` leaves. */ readonly root: Hex; readonly quoteTotal: bigint; readonly coinTotal: bigint; readonly quoteClaimed: bigint; readonly coinClaimed: bigint; /** Unix seconds. Claiming reverts at or after this; rolling over reverts before it. */ readonly expiresAt: bigint; readonly rolledOver: boolean; /** Derived: the window has passed, so this epoch can no longer be claimed. */ readonly expired: boolean; /** Derived: past the window and not yet swept back into the unallocated pool. */ readonly rollOverReady: boolean; } /** A distributor's immutable bindings and live balances. */ interface LaunchpadHolderDistributorState { readonly distributor: Address; /** The launch token, distributed as the **coin** side of every allocation. */ readonly token: Address; /** The quote asset, or the zero address when quote revenue is the native gas token. */ readonly quoteToken: Address; readonly feeEscrow: Address; readonly buybackVault: Address; /** Who may publish epochs. Distinct from `owner`, which may replace the publisher. */ readonly publisher: Address; readonly owner: Address; readonly epochCount: bigint; /** Seconds a published epoch stays claimable. `90 days` on the current deployment. */ readonly claimWindowSeconds: bigint; /** Held for published-but-unclaimed allocations; not available to a new epoch. */ readonly reservedQuote: bigint; readonly reservedCoin: bigint; /** Free balance a future epoch can allocate — harvested revenue plus expired rollovers. */ readonly unallocatedQuote: bigint; readonly unallocatedCoin: bigint; } /** Reads a distributor's bindings and balances in one pinned batch. */ declare function getLaunchpadHolderDistributorState(context: LaunchpadActionContext, distributor: Address, options?: LaunchpadReadOptions): Promise; /** * Reads one epoch. * * Reverts with the distributor's own `EpochNotFound` for an id at or beyond `epochCount` — there is * no zero-filled struct to mistake for a real epoch, so bound the id against * {@link getLaunchpadHolderDistributorState}'s `epochCount` rather than probing. * * `now` decides the derived `expired` / `rollOverReady` flags; pass the block timestamp you are * reading against rather than wall-clock time, or the two can disagree with the chain at the * boundary. */ declare function getLaunchpadHolderEpoch(context: LaunchpadActionContext, input: { readonly distributor: Address; readonly epochId: bigint; readonly now?: bigint; }, options?: LaunchpadReadOptions): Promise; /** Whether an account has already claimed a given epoch. Claiming twice reverts. */ declare function hasLaunchpadHolderClaimed(context: LaunchpadActionContext, input: { readonly distributor: Address; readonly epochId: bigint; readonly account: Address; }, options?: LaunchpadReadOptions): Promise; /** * Whether an account is excluded from claiming holder revenue. * * The set is fixed when the distributor is created: the zero address, the distributor itself, the * launch token and quote token contracts, the launch factory, the beacon and its implementation, * the authorized forwarder, and whatever system accounts the distributor factory was deployed with. * * Note what is **not** in it — the launch's own curve, whose address the factory cannot know in * advance. Keeping curve-held balances out of an allocation is the off-chain snapshot's job; this * check only rejects a claim, and only for the addresses above. */ declare function isLaunchpadHolderExcluded(context: LaunchpadActionContext, input: { readonly distributor: Address; readonly account: Address; }, options?: LaunchpadReadOptions): Promise; /** One holder allocation, as the proof service publishes it. */ interface LaunchpadHolderAllocation { /** * The **on-chain** epoch id. * * The proof service also carries database identifiers for its own routing, and they are not the * same number. Only this one may be sent to the contract — its API response names it * `onchain_epoch_id` for exactly that reason. */ readonly epochId: bigint; readonly account: Address; /** Quote-asset share. Either side may be zero, but not both — the contract rejects a zero claim. */ readonly quoteAmount: bigint; /** Launch-token share. */ readonly coinAmount: bigint; readonly proof: readonly Hex[]; } /** * Computes the Merkle leaf for an allocation. * * OpenZeppelin `StandardMerkleTree` over `[address, uint256, uint256]`, which double-hashes: * `keccak256(bytes.concat(keccak256(abi.encode(account, quoteAmount, coinAmount))))`. The second * hash is not decoration — it is what makes an internal node impossible to pass off as a leaf. */ declare function launchpadHolderLeaf(allocation: Pick): Hex; /** * Recomputes an allocation's Merkle root from its proof. * * Sorted-pair hashing, matching the contract's `_verify`. Compare the result against the epoch's * published `root` to confirm an allocation before spending gas on it. */ declare function launchpadHolderProofRoot(allocation: LaunchpadHolderAllocation): Hex; /** * Checks an allocation against an epoch's published root, locally. * * Worth doing before every claim. The contract's `InvalidMerkleProof` says only that something did * not line up, and the likeliest causes are silent ones: the proof service's database epoch id used * in place of the on-chain one, an amount rounded or reformatted in transit, or a proof fetched for * a different account. Recomputing the root locally separates "this allocation is wrong" from "this * epoch is wrong" before a transaction is built. */ declare function launchpadHolderAllocationMatchesRoot(allocation: LaunchpadHolderAllocation, root: Hex): boolean; /** * Prepares a holder claim. * * Anyone may submit it — the payout goes to `allocation.account`, not to the sender — so a product * can sponsor claims for its users. Both amounts being zero is rejected by the contract; so is a * second claim of the same epoch by the same account, an excluded account, and an epoch past its * window. * * The proof comes from the distributor project's proof service, and its `epochId` must be the * on-chain one. Validate the allocation against the epoch root first — see * {@link launchpadHolderAllocationMatchesRoot}. */ declare function prepareLaunchpadHolderClaim(context: LaunchpadWriteActionContext, input: { readonly distributor: Address; readonly allocation: LaunchpadHolderAllocation; }): Promise>; /** * Prepares several claims in one transaction. * * All-or-nothing: the contract loops under a single reentrancy guard, so one bad allocation reverts * the batch. Validate every allocation locally first, and expect the epochs to differ — a holder * with several unclaimed epochs is the case this exists for. */ declare function prepareLaunchpadHolderClaimMany(context: LaunchpadWriteActionContext, input: { readonly distributor: Address; readonly allocations: readonly LaunchpadHolderAllocation[]; }): Promise>; /** What a harvest or roll-over is expected to move, from simulating it. */ interface LaunchpadHolderSweepPreview { readonly distributor: Address; readonly quoteAmount: bigint; readonly coinAmount: bigint; } /** * Prepares `harvest`, pulling everything owed to this distributor into it. * * Permissionless, and a prerequisite for publishing: nothing counts towards `unallocatedQuote` / * `unallocatedCoin` until it has been harvested. It moves nothing to holders by itself. * * It gathers from three places, not just the escrow — worth knowing, because the third is where * buyback revenue eventually turns up: * * 1. the revenue harvester, if the distributor was configured with one; * 2. **`BuybackVault.release`**, whenever the launch has vested buyback tokens waiting. Buyback * spends part of the creator's gross on the launch token and vests it over five years, so that * share reaches holders here, later and as the coin side — not as quote at trade time; * 3. `FeeEscrow`, for both the quote asset and the launch token. * * The preview reports what the simulation says will arrive on each side. Zero on both is normal and * not an error: it means there was nothing to collect yet. */ declare function prepareLaunchpadHolderHarvest(context: LaunchpadWriteActionContext, distributor: Address): Promise>; /** * Prepares `rollOver`, returning an expired epoch's unclaimed remainder to the unallocated pool. * * Permissionless, and only after the claim window has closed — calling early reverts with * `ClaimWindowOpen` rather than doing nothing. The recovered amount funds a later epoch instead of * being stranded, so this is ordinary housekeeping, not a recovery path. */ declare function prepareLaunchpadHolderRollOver(context: LaunchpadWriteActionContext, input: { readonly distributor: Address; readonly epochId: bigint; }): Promise>; /** * The distributor factory's own view of a launch token's binding. * * Use it to confirm an address really is the official distributor for a token before showing it as * one — a launch may nominate any `creatorFeeRecipient` it likes, and only the registry can tell * the difference. */ declare function getLaunchpadHolderBinding(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise<{ readonly distributor: Address; readonly registered: boolean; }>; /** * The distributor factory's adapter revision, read from the chain. * * `createDistributor` demands `initializationData` be exactly `abi.encode(ADAPTER_VERSION)` — 32 * bytes, matching value — and rejects anything else with `InvalidInitializationData`. Reading it * rather than assuming means a factory upgraded to a later adapter fails loudly at the check * instead of silently at creation. */ declare function getLaunchpadHolderAdapterVersion(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** * Whether the distributor factory will distribute revenue in this quote asset. * * Its own allowlist, separate from the launch factory's `approvedQuoteTokens`: an asset can be * perfectly good for trading and still not be one this distributor project supports. Creation * rejects a disallowed asset with a bare `InvalidConfiguration`, which says nothing about which of * that function's several conditions failed — so check first when offering the holder-sharing * option for a given quote token. */ declare function isLaunchpadHolderQuoteTokenAllowed(context: LaunchpadActionContext, quoteToken: Address, options?: LaunchpadReadOptions): Promise; /** * Prepares the full curve sweep: protocol, creator, and the buyback settlement in one call. * * Permission is conditional rather than fixed. The fee sweep operator may always call it; the * launch's current creator fee recipient may too, but **only while there is no pending buyback** — * settling one performs an internal swap against the curve, which is restricted to the operator. * That is why `minBuybackTokensOut` is required whenever a buyback is pending: it is the slippage * floor for that swap. * * A buyback that cannot execute (price impact over the ceiling, or the reserved boundary in the * way) is not an error — the budget folds back into the creator's bucket and the sweep proceeds. * * **This does not touch partner balances.** It settles the protocol, creator and buyback buckets * only; each partner's accrual stays on the curve until `sweepPartner` is called for that specific * id ({@link prepareLaunchpadSweepBucket} with `bucket: "partner"`). A keeper that runs only this * leaves partner balances stranded indefinitely, with nothing failing to signal it. */ declare function prepareLaunchpadSweepFees(context: LaunchpadWriteActionContext, input: { readonly curve: Address; readonly minBuybackTokensOut?: bigint; }): Promise>; /** Prepares a single-bucket curve sweep, none of which perform an internal swap. */ declare function prepareLaunchpadSweepBucket(context: LaunchpadWriteActionContext, input: { readonly curve: Address; readonly bucket: "protocol" | "creator"; } | { readonly curve: Address; readonly bucket: "partner"; readonly partnerId: Hex; }): Promise>; /** A V4 pool's fee-sweep epoch state, which drives the paged settlement loop. */ interface LaunchpadPoolSweepState { readonly poolId: Hex; /** Epoch new swaps accrue into. */ readonly currentEpoch: bigint; /** * Epoch currently being settled, already decoded. * * The hook stores this **one-based** (`mapping(bytes32 => uint256 epochPlusOne)`), using zero to * mean "no sweep open". Passing the raw slot through as an epoch id is off by one, and every * `settlePoolFeeSweepPartners` / `finalizePoolFeeSweep` built from it reverts with * `InvalidConfiguration`. This field is the real epoch id, or `undefined` when nothing is * settling. */ readonly settlingEpochId?: bigint; /** Whether a sweep is open. `beginPoolFeeSweep` reverts while it is true. */ readonly isSettling: boolean; /** The hook's raw one-based slot, exposed for parity with on-chain debugging. */ readonly settlingEpochRaw: bigint; } /** Reads a graduated pool's epoch cursors, decoding the one-based settling slot. */ declare function getLaunchpadPoolSweepState(context: LaunchpadActionContext, poolId: Hex, options?: LaunchpadReadOptions): Promise; /** * One epoch's partner sweep accounting, which RC2 made necessary rather than merely useful. * * Before RC2 a sweep that hit the internal price-impact ceiling reverted the whole batch, so a * keeper only had to retry. RC2 converts what it can and leaves the rest: `launchInputConsumed` can * be less than `launchInputTotal`, the unconsumed partner remainder rolls into the next epoch, and * ordinary unconsumed balances stay in the hook's pending ledger. Progress therefore has to be read * rather than inferred from a transaction succeeding. */ interface LaunchpadPartnerEpochAccounting { readonly poolId: Hex; readonly epochId: bigint; /** Launch tokens attributed to partners when the epoch closed. */ readonly partnerLaunchInputTotal: bigint; /** How much of that was actually converted this round. Less than the total after a partial fill. */ readonly partnerLaunchInputConsumed: bigint; /** Consumed input not yet handed to a partner by the paging loop. */ readonly partnerLaunchInputConsumedRemaining: bigint; /** Consumed input already settled out to partners, from the RC2 `partnerLaunchInputSettled` getter. */ readonly partnerLaunchInputSettled: bigint; readonly partnerConvertedQuoteTotal: bigint; readonly partnerConvertedQuoteRemaining: bigint; readonly partnerDirectQuoteTotal: bigint; readonly partnerDirectQuoteRemaining: bigint; readonly activePartnerCount: bigint; readonly settledPartnerCount: bigint; /** Total launch-token input consumed by the whole sweep, partners and non-partners alike. */ readonly totalLaunchInput: bigint; readonly totalQuoteOutput: bigint; /** Whether this epoch is the one currently being settled. */ readonly settling: boolean; /** * Whether `finalizePoolFeeSweep` would succeed for this epoch. * * The hook checks five separate conditions, not just the partner count: every active partner * settled, the settled launch input matching the epoch's total, and all three remainders * (`partnerLaunchInputConsumedRemaining`, `partnerConvertedQuoteRemaining`, * `partnerDirectQuoteRemaining`) drained to zero. Finalizing on the count alone reverts with * `InvalidConfiguration`. * * The sweep must also still be the open one — `getLaunchpadPoolSweepState(...).settlingEpochId` * has to equal this epoch, which this read cannot see on its own. */ readonly finalizeReady: boolean; /** Every active partner has been paged through. One of the five conditions behind {@link finalizeReady}. */ readonly allPartnersSettled: boolean; } /** * Reads the full settlement state of one epoch, including RC2's `partnerLaunchInputSettled`. * * This is the read a keeper loop should drive off: `allPartnersSettled` says whether finalizing can * succeed, and the consumed-versus-total figures say whether a partial conversion left work behind. */ declare function getLaunchpadPartnerEpochAccounting(context: LaunchpadActionContext, input: { readonly poolId: Hex; readonly epochId: bigint; }, options?: LaunchpadReadOptions): Promise; /** Whether a partner accrued in, and has been settled for, a given epoch. */ declare function getLaunchpadPartnerEpochStatus(context: LaunchpadActionContext, input: { readonly poolId: Hex; readonly epochId: bigint; readonly partnerId: Hex; }, options?: LaunchpadReadOptions): Promise<{ readonly active: boolean; readonly settled: boolean; }>; /** * Prepares step one of a V4 pool fee sweep. * * Note the argument asymmetry, which is easy to get wrong: this step takes the **token**, while * `settlePoolFeeSweepPartners` and `finalizePoolFeeSweep` take the **poolId**. Resolve the pool id * with `getLaunchpadPoolId` before continuing the sequence. * * Only one epoch may be settling at a time — swaps keep accruing into the next epoch meanwhile, but * a second sweep cannot start until this one is finalized. Check * `getLaunchpadPoolSweepState(...).isSettling` first rather than discovering it as an * `InvalidConfiguration`. * * **Neither minimum may be zero when its leg has work to do.** The hook rejects the entire sweep * with `MinimumOutputRequired` if `minConversionQuoteOut` is zero while there is launch-token input * to convert, or if `minBuybackTokensOut` is zero while a buyback is pending — and a buyback is * pending on any pool whose creator has it enabled, which is the default. Passing zero as a * "no opinion on slippage" placeholder is the natural mistake and stops the sweep outright. */ declare function prepareLaunchpadBeginPoolFeeSweep(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly minConversionQuoteOut: bigint; readonly minBuybackTokensOut: bigint; }): Promise>; /** * Prepares one page of partner settlement. * * The active partner set for an epoch is rebuilt off-chain from `PartnerFeeAccrued` events, keyed * `(poolId, epochId, partnerId)`; `partnerActive`/`partnerSettled` are the on-chain check. There is * **no protocol limit** on partner count or page size — any batch ceiling is the caller's own gas * budget, and code must not assume a fixed 32 or 64. */ declare function prepareLaunchpadSettlePoolFeeSweepPartners(context: LaunchpadWriteActionContext, input: { readonly poolId: Hex; readonly epochId: bigint; readonly partnerIds: readonly Hex[]; }): Promise>; /** Prepares the final step, closing the epoch. Only valid once every active partner is settled. */ declare function prepareLaunchpadFinalizePoolFeeSweep(context: LaunchpadWriteActionContext, input: { readonly poolId: Hex; readonly epochId: bigint; }): Promise>; /** `bytes32(0)`: the reserved "no partner on this trade" id, which can never be registered. */ declare const NO_PARTNER_ID: Hex; /** Reads one partner's registry entry. */ declare function getLaunchpadPartner(context: LaunchpadActionContext, partnerId: Hex, options?: LaunchpadReadOptions): Promise; /** Reads the registry-wide default and maximum partner share. */ declare function getLaunchpadPartnerPolicy(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** Whether a partner id can be attached to a trade, and what it would earn if so. */ interface LaunchpadPartnerUsability { readonly partnerId: Hex; /** A trade carrying this id will not revert. True for the zero id and for any registered id. */ readonly usable: boolean; /** * A trade carrying this id will actually accrue a partner fee. False for a disabled partner. * * Disabling is forward-looking only: it stops new accrual and blocks the partner's own claims, * but it does not block settling epochs they already accrued in. A keeper must keep paging a * disabled partner through historical settlement, or those epochs never finalize. */ readonly earning: boolean; readonly shareOfPlatformBps: number; readonly reason?: "notRegistered" | "disabled"; } /** * Resolves what attaching `partnerId` to a trade would do. * * The three outcomes are genuinely different and a UI should not collapse them. The zero id trades * normally with no attribution. A **registered but disabled** id also trades normally and is still * recorded in the event — it simply earns nothing, and the fee stays with the platform. An * **unregistered non-zero** id reverts the whole trade, which is the case worth catching before * sending. */ declare function getLaunchpadPartnerUsability(context: LaunchpadActionContext, partnerId: Hex, options?: LaunchpadReadOptions): Promise; /** * Encodes a partner id as Uniswap V4 `hookData` for a swap on a graduated pool. * * The frozen ABI is exactly `abi.encode(bytes32)` and empty bytes for no partner. The hook * validates the length strictly: anything else — a packed encoding, a padded blob, a zero-length * value that is not truly empty — reverts the swap rather than being ignored. */ declare function encodeLaunchpadPartnerHookData(partnerId?: Hex): Hex; /** * Reads the controller a partner has proposed but not yet handed over to. * * The handover is propose/accept in two steps, and a partner being disabled clears any pending * proposal outright rather than parking it. */ declare function getLaunchpadPendingPartnerController(context: LaunchpadActionContext, partnerId: Hex, options?: LaunchpadReadOptions): Promise
; /** Raised when a read is attempted with an input the factory would reject outright. */ declare class InvalidLaunchpadReadInputError extends Error { readonly field: string; constructor(field: string, message: string); } /** * Raised when a composite read that must observe one block is asked to use a tag with no stable * height. `pending` names a block that does not exist yet, so nothing can be pinned to it. */ declare class UnpinnableBlockTagError extends Error { readonly blockTag: string; constructor(blockTag: string); } /** * Resolves a concrete height that every part of a composite read can be pinned to. * * Reads that combine several calls must not each resolve `latest` independently: the chain head can * advance between them, silently mixing one block's state with another block's height. That matters * more in V2 than it did in V3 — a curve snapshot is assembled from several separate getters rather * than one struct read, so an unpinned read can produce reserves that never simultaneously existed. */ declare function resolvePinnedBlockNumber(context: LaunchpadActionContext, options?: LaunchpadReadOptions): Promise; /** * True when `token` was launched by this deployment's factory. * * Frontends that let a user paste an arbitrary address must check this first: unlike V3's * `getTokenState`, the V2 record getter does not revert for a stranger address — it returns a * zero-filled struct whose `curve` is the zero address. */ declare function isLaunchpadToken(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** * Resolves a launch token's `BondingCurve` address. * * The single most-used read in V2: the factory no longer holds per-token state or trading entry * points, so nearly every other call needs the curve first. Callers making several calls for one * token should resolve it once and pass it down rather than re-reading per call. */ declare function getLaunchpadCurveAddress(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise
; /** Reads the launch's immutable economics record. Throws for a token this factory did not launch. */ declare function getLaunchpadLaunchRecord(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** Reads the two-step graduation record. Available for any launched token, in every status. */ declare function getLaunchpadGraduation(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** * Reads a curve's live pricing state at one block. * * `phantomQuote` and `graduationThreshold` are read from the **curve**, never from the deployment's * pinned quote-token economics, even though the two normally agree. Both are immutable per curve, * frozen at creation, while governance can move the quote token's economics afterwards with * `setQuoteTokenEconomics`. Preferring the pinned value would therefore misprice every curve * created before such a change: `reservedTokens` derives from these two, so a stale threshold * shifts the graduation boundary and silently corrupts both the sellable supply and the * partial-fill point. */ declare function getLaunchpadCurveState(context: LaunchpadActionContext, input: { readonly curve: Address; }, options?: LaunchpadReadOptions): Promise; /** Reads a launch's record, curve state and graduation status, all pinned to one block. */ declare function getLaunchpadTokenState(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** Reads the fees a curve has accrued but not yet swept. */ declare function getLaunchpadCurvePendingFees(context: LaunchpadActionContext, curve: Address, options?: LaunchpadReadOptions): Promise; /** Reads one partner's unswept balance on a curve, keyed by partner id. */ declare function getLaunchpadCurvePendingPartnerFee(context: LaunchpadActionContext, curve: Address, partnerId: `0x${string}`, options?: LaunchpadReadOptions): Promise; /** * Whether an account is exempt from the opening snipe tax on this curve. * * Must be asked about the **token recipient** of a trade, never the payer: a router submitting on * a trader's behalf neither lends nor borrows its own exemption status. */ declare function isLaunchpadTaxExempt(context: LaunchpadActionContext, curve: Address, account: Address, options?: LaunchpadReadOptions): Promise; /** * The snipe tax a given token recipient would pay right now, straight from the curve. * * Prefer this over recomputing locally when the exact rate matters: the contract resolves it * against `block.timestamp`, and a rate computed off the client clock can differ by a full decay * step near a second boundary. */ declare function getLaunchpadCurrentSnipeTaxBps(context: LaunchpadActionContext, curve: Address, tokenRecipient: Address, options?: LaunchpadReadOptions): Promise; /** On-chain buy quote: tokens received for `netQuoteIn`, already net of fees, capped at the boundary. */ declare function quoteLaunchpadBuyNet(context: LaunchpadActionContext, curve: Address, netQuoteIn: bigint, options?: LaunchpadReadOptions): Promise; /** On-chain exact-output quote: net quote required to receive exactly `tokenOut`. */ declare function quoteLaunchpadNetRequiredToBuy(context: LaunchpadActionContext, curve: Address, tokenOut: bigint, options?: LaunchpadReadOptions): Promise; /** On-chain sell quote: gross quote the curve gives up for `tokenIn`, before fees. */ declare function quoteLaunchpadSellGross(context: LaunchpadActionContext, curve: Address, tokenIn: bigint, options?: LaunchpadReadOptions): Promise; /** Reads `LauncherToken`'s permanently stored structured info. */ declare function getLaunchpadTokenInfo(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise; /** Reads name, symbol and decimals for any ERC-20 at one block. */ declare function getLaunchpadErc20Metadata(context: LaunchpadActionContext, asset: Address, options?: LaunchpadReadOptions): Promise; /** * Reads an ERC-20 allowance. * * The spender differs by operation in V2, and getting it wrong produces an approval that looks * right and still reverts: **creation** (`createToken`, and `launchAndBuy` through the forwarder) * is pulled by the **factory**, while **trading** (`buyExactIn`/`sellExactIn`) is pulled by the * token's own **curve**. */ declare function getErc20Allowance(context: LaunchpadActionContext, asset: Address, owner: Address, spender: Address, options?: LaunchpadReadOptions): Promise; /** Reads an ERC-20 balance. */ declare function getErc20Balance(context: LaunchpadActionContext, asset: Address, owner: Address, options?: LaunchpadReadOptions): Promise; /** * Graduation progress on the Token side, matching the contract's own boundary. * * Reported against initially-sellable supply rather than a quote target, so it saturates at exactly * 100% — V3's quote-denominated progress could be overshot by one large buy. Progress can also move * backwards, which is correct: a sell returns tokens to the curve. * * Takes the supply from the curve state rather than as a separate argument, so a caller cannot pass * one that disagrees with the reservedTokens the same state was built from. */ declare function getLaunchpadGraduationProgress(curveState: LaunchpadCurveState): LaunchpadGraduationProgress; /** * Derives trade availability from already-read state, so a UI can render the gate and the current * rates without duplicating `_requireTradingOpen`'s rules. * * `snipeTaxBps` is reported for a **non-exempt** recipient. An exempt one always pays zero; resolve * that per recipient with {@link isLaunchpadTaxExempt} rather than assuming this value applies. */ declare function toLaunchpadTradeAvailability(state: LaunchpadTokenState, input: { readonly blockNumber: bigint; readonly timestamp: bigint; }): LaunchpadTradeAvailability; /** `LaunchFactory.TokenCreated`. The only authority on a new launch's token and curve addresses. */ interface LaunchpadTokenCreatedEvent { readonly token: Address; readonly curve: Address; readonly creator: Address; readonly quoteToken: Address; readonly launchConfigId: bigint; readonly graduationThreshold: bigint; readonly tokenInfoHash: Hex; readonly creatorFeeRecipient: Address; readonly buybackEnabled: boolean; readonly creatorTaxBps: number; } /** * `BondingCurve.CurveTrade`, direction-normalized. * * `quoteSpentOrReceived` swaps meaning by direction, which is the easiest thing here to account * wrong: on a buy it is what the payer actually spent (already net of any boundary refund), and on * a sell it is what the recipient received after fees. `grossQuoteBasis` is the amount all three * fee components were charged against, and is the right field to sum for volume in both * directions. * * `feePayer` and `tokenRecipient` are deliberately separate: the snipe tax is resolved against the * **recipient**, so a router paying on someone's behalf does not lend or borrow its exemption. */ interface LaunchpadTradeEvent { readonly token: Address; /** The curve that emitted this. Cross-check against `curveFor(token)` before trusting a log from an unrecognized address. */ readonly curve: Address; readonly feePayer: Address; readonly tokenRecipient: Address; /** `bytes32(0)` for no partner. A non-zero id here does **not** imply the partner earned a fee — a disabled partner is recorded but paid nothing. */ readonly partnerId: Hex; readonly side: "buy" | "sell"; readonly tokenAmount: bigint; readonly grossQuoteBasis: bigint; readonly quoteSpentOrReceived: bigint; readonly baseFee: bigint; readonly snipeTax: bigint; readonly creatorTax: bigint; } /** `BondingCurve.FeeAllocated`: how one trade's fee basis was split across the buckets. */ interface LaunchpadFeeAllocatedEvent { readonly token: Address; readonly curve: Address; readonly partnerId: Hex; readonly feeBasis: bigint; readonly creatorImmediate: bigint; readonly buybackBudget: bigint; readonly partnerFee: bigint; readonly platformNet: bigint; readonly creatorTax: bigint; } /** `BondingCurve.SnipeTaxCharged`, keyed on the token recipient the tax was resolved against. */ interface LaunchpadSnipeTaxChargedEvent { readonly curve: Address; readonly tokenRecipient: Address; readonly amount: bigint; } /** `BondingCurve.CurveFeesSwept`: a bucket left the curve for the escrow. */ interface LaunchpadCurveFeesSweptEvent { readonly token: Address; readonly curve: Address; readonly beneficiary: Address; /** `bytes32(0)` unless this was a partner sweep. */ readonly partnerId: Hex; readonly asset: Address; readonly amount: bigint; } /** * `BondingCurve.CurveBuybackSettled`. * * `executed: false` is not a failure — the budget folds back into the creator's bucket when the * internal swap would breach the price-impact ceiling or the reserved boundary. */ interface LaunchpadBuybackSettledEvent { readonly token: Address; readonly curve: Address; readonly quoteAmount: bigint; readonly tokenAmount: bigint; readonly executed: boolean; } /** Graduation lifecycle, from the coordinator. Both steps are permissionless and separately retryable. */ interface LaunchpadGraduationEvent { readonly token: Address; readonly kind: "swept" | "poolCreated" | "emergencyExited"; readonly tokenAmount: bigint; readonly quoteAmount: bigint; /** Present on `poolCreated`: the V4 position NFT minted for the graduated liquidity. */ readonly positionId?: bigint; /** Present on `emergencyExited`: the distributor holding the redeemable quote. */ readonly distributor?: Address; readonly quoteToken?: Address; } /** `FeeEscrow` credit and claim events, for both plain recipients and partners. */ interface LaunchpadFeeEscrowEvent { readonly kind: "credited" | "claimed"; readonly beneficiary: "recipient" | "partner"; /** Set when `beneficiary` is `"recipient"`, or on a partner **claim** (the paid-out recipient). */ readonly recipient?: Address; /** Set when `beneficiary` is `"partner"`. */ readonly partnerId?: Hex; /** Set on a credit: whoever funded it. Credits are permissionless. */ readonly payer?: Address; readonly asset: Address; readonly amount: bigint; } /** `BuybackVault` lock and release events. */ interface LaunchpadBuybackVaultEvent { readonly kind: "locked" | "released"; readonly token: Address; readonly amount?: bigint; readonly creatorAmount?: bigint; readonly protocolAmount?: bigint; } /** `EmergencyDistributor` lifecycle, emitted by the per-launch distributor. */ interface LaunchpadEmergencyDistributorEvent { readonly kind: "created" | "activated" | "redeemed" | "donatedTokensSynced" | "orphanedQuoteReleased"; /** The distributor that emitted this; the only identifier `activated` and `redeemed` carry. */ readonly distributor: Address; readonly launchToken?: Address; readonly quoteToken?: Address; readonly account?: Address; readonly recipient?: Address; readonly tokenIn?: bigint; readonly quoteOut?: bigint; readonly sweptTokens?: bigint; readonly sweptQuote?: bigint; readonly initialRedeemableSupply?: bigint; readonly amount?: bigint; } /** `MemeHook` V4 pool fee and partner-epoch events. */ interface LaunchpadPoolFeeEvent { readonly kind: "allocated" | "partnerAccrued" | "sweepBegun" | "partnersSettled" | "sweepFinalized" | "currencyConverted" | "feesRescued" | "partnerFeesRescued"; readonly poolId?: Hex; readonly token?: Address; readonly partnerId?: Hex; readonly epochId?: bigint; readonly amount?: bigint; /** Asset the rescue moved. Set on the two RC2 rescue kinds. */ readonly asset?: Address; /** Set on `feesRescued`, which settles the protocol and creator sides in one call. */ readonly protocolAmount?: bigint; readonly creatorAmount?: bigint; } /** * A Holder Fee Sharing launch, reported from both sides of the atomic creation. * * The forwarder emits `HolderSharingLaunchCreated` and the distributor factory emits * `DistributorCreated` in the same transaction. They are kept as separate entries rather than * merged, because reconciling them is the point: a launch that carries only one of the two is not * an official holder-sharing launch, and the migration guide is explicit that a mismatch must be * flagged rather than quietly accepted. */ interface LaunchpadHolderSharingEvent { readonly source: "forwarder" | "distributorFactory"; readonly creator: Address; readonly token: Address; readonly distributor: Address; /** Present on the forwarder's event. */ readonly curve?: Address; /** Present on the factory's event, along with the two below. */ readonly launchSalt?: Hex; readonly quoteToken?: Address; readonly feeEscrow?: Address; } /** * A Holder Distributor's own lifecycle, emitted by the per-launch distributor. * * Reported with the emitting address, like the other per-launch contracts: the parser cannot know a * distributor's address up front, so confirm it against `distributorForToken(token)` before * trusting a log from an arbitrary third-party receipt. */ interface LaunchpadHolderDistributorEvent { readonly kind: "epochPublished" | "claimed" | "rolledOver" | "harvested"; readonly distributor: Address; readonly epochId?: bigint; readonly account?: Address; /** Merkle root, on `epochPublished`. */ readonly root?: Hex; /** Opaque publisher metadata, on `epochPublished`. */ readonly metadata?: Hex; readonly expiresAt?: bigint; /** Quote-side amount: totals on publish, the claimed or rolled-over amount otherwise. */ readonly quoteAmount?: bigint; /** Launch-token side of the same. */ readonly coinAmount?: bigint; } /** * An automatic graduation attempt that reverted, added in RC2. * * **This does not mean the transaction failed.** RC2 tries to graduate a launch as soon as a buy * (or a creation's initial buy) empties the sellable supply. That attempt is wrapped in a `try`, so * when it reverts the trade still succeeds and only this event is emitted. Treating it as a failed * purchase is the mistake it exists to make visible; the launch simply stays `NotGraduated` and the * ordinary permissionless `graduate(token)` path picks it up. */ interface LaunchpadAutoGraduationFailedEvent { readonly token: Address; /** Gas remaining when the attempt gave up; useful for telling an out-of-gas retry from a real revert. */ readonly gasRemaining: bigint; /** Contract that emitted it — the factory after an initial buy, otherwise the launch's own curve. */ readonly emitter: Address; } /** Per-launch configuration changes the factory records after creation. */ interface LaunchpadLaunchConfigEvent { readonly kind: "creatorFeeRecipientUpdated" | "buybackEnabledUpdated" | "launchTaxExemptionAdded"; readonly token: Address; readonly previousRecipient?: Address; readonly newRecipient?: Address; readonly enabled?: boolean; readonly caller?: Address; readonly account?: Address; } /** Everything this SDK understands from one receipt, grouped by concern. */ interface LaunchpadReceiptEvents { readonly tokenCreated: readonly LaunchpadTokenCreatedEvent[]; readonly trades: readonly LaunchpadTradeEvent[]; readonly feeAllocations: readonly LaunchpadFeeAllocatedEvent[]; readonly snipeTaxCharges: readonly LaunchpadSnipeTaxChargedEvent[]; readonly curveFeesSwept: readonly LaunchpadCurveFeesSweptEvent[]; readonly buybackSettlements: readonly LaunchpadBuybackSettledEvent[]; readonly graduation: readonly LaunchpadGraduationEvent[]; readonly feeEscrow: readonly LaunchpadFeeEscrowEvent[]; readonly buybackVault: readonly LaunchpadBuybackVaultEvent[]; readonly emergencyDistributor: readonly LaunchpadEmergencyDistributorEvent[]; readonly poolFees: readonly LaunchpadPoolFeeEvent[]; /** RC2 auto-graduation attempts that reverted without failing their transaction. */ readonly autoGraduationFailures: readonly LaunchpadAutoGraduationFailedEvent[]; /** Both halves of a Holder Fee Sharing creation; reconcile them before trusting either. */ readonly holderSharing: readonly LaunchpadHolderSharingEvent[]; /** Epoch and claim activity on a per-launch Holder Distributor. */ readonly holderDistributor: readonly LaunchpadHolderDistributorEvent[]; readonly launchConfig: readonly LaunchpadLaunchConfigEvent[]; /** Tokens locked permanently in the `LaunchLocker` to hold the graduation price. */ readonly permanentLocks: readonly { readonly token: Address; readonly amount: bigint; }[]; } /** * Decodes every Launchpad event in a receipt. * * Logs from the deployment's singleton contracts are routed strictly by `log.address`, matching the * indexer spec's rule that source must never be inferred from the topic alone — several contracts * share the same `ILaunchpadEvents` declarations, so an event name does not identify its emitter. * * Per-launch contracts are the exception, and necessarily so: a `BondingCurve` and an * `EmergencyDistributor` live at addresses derived per launch, which a receipt parser cannot know * up front. Their logs are decoded from any address that is not one of the singletons, and the * emitting address is reported on every such event (`curve` / `distributor`) so a consumer can * confirm it against `curveFor(token)` or `predictDistributor(...)` before trusting it. For a * receipt from a transaction this SDK prepared that is a formality; for an arbitrary third-party * receipt it is not, and should be checked. */ declare function parseLaunchpadReceiptEvents(deployment: LaunchpadDeployment, receipt: TransactionReceipt): LaunchpadReceiptEvents; /** * Resolves the token and curve addresses a creation produced. * * `TokenCreated` is the only authority: `predictLaunchAddresses` is a preview that says nothing * about whether the launch actually happened, and the curve address is not derivable from the * token address alone. */ declare function createdLaunchAddresses(deployment: LaunchpadDeployment, receipt: TransactionReceipt): { readonly token: Address; readonly curve: Address; } | undefined; /** Confirmed transaction plus the Launchpad events decoded from its receipt. */ interface LaunchpadTransactionResult extends SdkTransactionResult { readonly events: LaunchpadReceiptEvents; } /** * Waits for a transaction and decodes its Launchpad events. * * A reverted receipt is reported as `status: "reverted"` rather than thrown, so a caller can tell * "the chain rejected this" apart from "the request never landed". Events are still parsed, which * is empty for a revert. */ declare function waitForLaunchpadTransaction(context: LaunchpadActionContext, hash: Hash, options?: { readonly confirmations?: number; }): Promise; declare function requireLaunchpadWriteAccount(context: LaunchpadWriteActionContext): Promise; declare function simulateLaunchpadWrite(context: LaunchpadWriteActionContext, parameters: Record): Promise<{ request: Record; result: unknown; }>; /** * Re-estimates a write and returns a request with enough headroom for RC2's in-transaction * graduation attempt. * * Only call this for a write that can actually trigger one — a buy that empties the curve, or a * creation whose initial buy does. Estimation failures are swallowed on purpose: the caller has * already simulated successfully, so a failure here means the node would not estimate, and the * right outcome is the unmodified request (the wallet estimates as before, and graduation stays * best-effort) rather than a broken prepare. */ declare function withAutoGraduationGasHeadroom(context: LaunchpadWriteActionContext, request: Record): Promise>; declare function assertLaunchpadCanSpend(context: LaunchpadWriteActionContext, input: { readonly asset: Address; readonly owner: Address; readonly requiredAmount: bigint; /** * Contract that will pull the funds. Defaults to the factory, which is right for every curve * write; the emergency-exit vault pulls its own redemptions, so that path passes it explicitly. */ readonly spender?: Address; }): Promise; /** Base class for every stable Launchpad failure, so callers can branch on one instanceof. */ declare class LaunchpadError extends Error { constructor(message: string, options?: { cause?: unknown; }); } /** * The launch is not in a lifecycle state that permits the attempted operation. * * Covers `CurveTradingClosed`, `AlreadyGraduated`, `NotReadyToGraduate` and * `InvalidGraduationState`. In V2 a curve closes to trading the moment `sellableTokens` hits zero — * before anyone calls `graduate` — so "closed" and "graduated" are genuinely different states and * `status` distinguishes them when the SDK knows it. */ declare class LaunchpadPhaseUnavailableError extends LaunchpadError { readonly status?: LaunchpadGraduationStatus; constructor(status?: LaunchpadGraduationStatus, options?: { cause?: unknown; }); } /** * `CurveTradingClosed`: the curve has sold through to its reserved floor, or has graduated. * * Not a pause — Production V2 has no pause mechanism at all. Once this fires for a given launch it * is permanent: the curve never reopens, and the token trades on its V4 pool instead. */ declare class LaunchpadTradingClosedError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** `UnknownLaunchToken`-equivalent: the address is not a token this factory launched. */ declare class LaunchpadUnknownTokenError extends LaunchpadError { readonly token?: Address; constructor(token?: Address, options?: { cause?: unknown; }); } /** `CreatorDenied`: the creator is on the factory's denylist, which outranks public launch. */ declare class LaunchpadCreatorDeniedError extends LaunchpadError { readonly creator?: Address; constructor(creator?: Address, options?: { cause?: unknown; }); } /** * `LaunchNotPermitted`: public launch is disabled and the creator is not whitelisted. * * Distinct from {@link LaunchpadCreatorDeniedError}: this is a gate that is closed for everyone * except an allowlist, not a sanction against one account. */ declare class LaunchpadLaunchNotPermittedError extends LaunchpadError { readonly creator?: Address; constructor(creator?: Address, options?: { cause?: unknown; }); } /** * `EconomicsHashMismatch`: the economics template moved between building the parameters and * submitting them. * * Only reachable when `expectedEconomics` was set to a non-zero value; passing `bytes32(0)` opts * out of the check entirely. Recover by re-reading `validateAndResolve` and rebuilding the hash. */ declare class LaunchpadEconomicsHashMismatchError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** The caller is not the account the operation requires (creator, controller, recipient, owner). */ declare class LaunchpadUnauthorizedError extends LaunchpadError { constructor(message?: string, options?: { cause?: unknown; }); } /** There is nothing to claim, sweep, or release for this beneficiary. */ declare class LaunchpadNothingToClaimError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** A two-step governance action was attempted before its timelock elapsed, or after it expired. */ declare class LaunchpadGovernanceDelayError extends LaunchpadError { constructor(message?: string, options?: { cause?: unknown; }); } /** A two-step action was executed or accepted with no matching pending proposal. */ declare class LaunchpadNoPendingProposalError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** `EmergencyExitNotReady`: the seven-day emergency exit delay has not elapsed. */ declare class LaunchpadEmergencyExitNotReadyError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** Partner registry and partner-attribution failures. */ declare class LaunchpadPartnerError extends LaunchpadError { constructor(message: string, options?: { cause?: unknown; }); } /** The quote moved past the caller's tolerance; re-quote before retrying. */ declare class LaunchpadSlippageError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** The deadline elapsed. The transaction must be rebuilt, never replayed. */ declare class LaunchpadDeadlineExpiredError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** `InvalidAmount`: an amount was rejected outright — zero, or past a bound. */ declare class LaunchpadInvalidAmountError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** * `TradeFeeConsumesInput`: curve fee + snipe tax + creator tax add up to at least the gross amount, * leaving nothing for the trade itself. Distinct from {@link LaunchpadInvalidAmountError} because * the fix is specific — increase the trade size or wait for the snipe tax to decay. */ declare class LaunchpadTradeFeeConsumesInputError extends LaunchpadError { readonly totalFee?: bigint; readonly gross?: bigint; constructor(totalFee?: bigint, gross?: bigint, options?: { cause?: unknown; }); } /** * `InsufficientQuoteReserve`: a sell's net proceeds would exceed the curve's real, non-phantom * quote reserve (`trackedQuote - quoteFeeBalance - creatorTaxBalance`). * * `phantomQuote` lets the curve quote a nonzero price before any real quote has arrived, so a large * sell early in a curve's life can be priced above what the curve actually holds. */ declare class LaunchpadInsufficientQuoteReserveError extends LaunchpadError { readonly available?: bigint; readonly requested?: bigint; constructor(available?: bigint, requested?: bigint, options?: { cause?: unknown; }); } /** The factory rejected the supplied creation parameters. */ declare class LaunchpadInvalidCreateParamsError extends LaunchpadError { constructor(message?: string, options?: { cause?: unknown; }); } /** * An internal accounting or balance-delta invariant failed. Against a verified deployment this * almost always means the asset is not a standard, non-fee-on-transfer ERC-20. */ declare class LaunchpadAccountingInvariantError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** * A token or native transfer failed. * * `prepare*` checks balance and allowance ahead of simulation precisely so this does not surface as * an unexplained failure, so reaching it means one of the conditions those checks cannot see held * instead: the asset takes a fee on transfer, is paused or blacklisting, or the balance moved * between preparing and broadcasting. */ declare class LaunchpadTransferFailedError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** * Catch-all for deployment/configuration failures a normal trading UI should never hit. * * Surfacing these distinctly (rather than falling through to the generic core mapping) makes a * misconfigured, half-wired, or tampered deployment visibly different from an ordinary trade * failure. */ declare class LaunchpadProtocolConfigurationError extends LaunchpadError { constructor(options?: { cause?: unknown; }); } /** An ERC-20 approval is required before the operation can succeed. */ declare class LaunchpadApprovalRequiredError extends LaunchpadError { readonly asset: Address; readonly spender: Address; readonly requiredAmount: bigint; constructor(asset: Address, spender: Address, requiredAmount: bigint); } /** * The account cannot cover the amount a transfer would move. * * Checked alongside the allowance during `prepare*`, because the contracts move funds through * `SafeERC20`, which collapses every underlying failure into one opaque revert. */ declare class LaunchpadInsufficientBalanceError extends LaunchpadError { readonly asset: Address; readonly owner: Address; readonly requiredAmount: bigint; readonly balance: bigint; constructor(asset: Address, owner: Address, requiredAmount: bigint, balance: bigint); } /** A prepared transaction was sent from a different account than the one it was prepared for. */ declare class PreparedAccountMismatchError extends LaunchpadError { readonly expectedAccount: Address; readonly actualAccount: Address; constructor(expectedAccount: Address, actualAccount: Address); } /** * The value passed to a send call did not originate from this SDK's prepare pipeline, or belongs to * a different deployment. Broadcasting it would skip simulation and the safety checks around it. */ declare class ForgedPreparedTransactionError extends LaunchpadError { constructor(message: string); } /** A write was attempted on a client constructed without a Wallet Client. */ declare class MissingWalletClientError extends LaunchpadError { constructor(); } /** The wallet is connected to a different chain than the requested deployment. */ declare class WrongWalletChainError extends LaunchpadError { readonly expectedChainId: number; readonly actualChainId?: number; constructor(expectedChainId: number, actualChainId?: number); } /** * Every ABI error name this package maps, exported so the coverage test can assert the map is * exhaustive against the generated ABIs rather than against a hand-kept list. */ declare const mappedLaunchpadRevertNames: readonly string[]; /** Extracts the reverted custom-error name from a viem error chain, if present. */ declare function revertErrorName(error: unknown): string | undefined; /** * Maps a contract failure onto a stable SDK error using the decoded custom-error name, never the * message text. Unrecognized failures fall back to the shared core error codes, preserving the * original cause and request metadata. */ declare function toLaunchpadError(error: unknown): Error; /** `LaunchConstants` byte ceilings, measured on UTF-8 bytes rather than UTF-16 code units. */ declare const MAX_NAME_BYTES = 64; declare const MAX_SYMBOL_BYTES = 16; declare const MAX_LOGO_BYTES = 512; declare const MAX_DESCRIPTION_BYTES = 2048; declare const MAX_SOCIAL_BYTES = 256; /** `LaunchConstants.MAX_EXTRA_LAUNCH_TAX_EXEMPTIONS`, on top of the automatic ones. */ declare const MAX_EXTRA_LAUNCH_TAX_EXEMPTIONS = 32; /** `LaunchPolicyConfiguration.MAX_COMBINED_BASE_AND_CREATOR_TAX_BPS`. */ declare const MAX_COMBINED_BASE_AND_CREATOR_TAX_BPS = 2000; /** `Socials`, in the struct's own field order. */ interface LaunchpadSocials { readonly twitter: string; readonly telegram: string; readonly discord: string; readonly website: string; readonly farcaster: string; } /** * `CreateTokenParams`, field for field. * * Defined here rather than in `types/` because this module is what enforces the struct's rules; the * domain-types rewrite should re-export this rather than restate it, so the validation and the * shape can never drift apart. */ interface LaunchpadCreateTokenParams { readonly name: string; readonly symbol: string; readonly logo: string; readonly description: string; readonly socials: LaunchpadSocials; readonly quoteToken: Address; readonly launchConfigId: bigint; readonly expectedEconomics: Hex; readonly launchTaxExemptions: readonly Address[]; readonly creatorFeeRecipient: Address; readonly buybackEnabled: boolean; readonly creatorTaxBps: number; readonly creatorInitialBuyQuoteRaw: bigint; readonly creatorInitialBuyRecipient: Address; readonly minInitialTokenOut: bigint; readonly deadline: bigint; readonly salt: Hex; } /** The `TokenInfo` field names the contract tags `TokenInfoTooLong` with. */ type LaunchpadTokenInfoField = "name" | "symbol" | "logo" | "description" | "twitter" | "telegram" | "discord" | "website" | "farcaster"; /** * One creation rule the parameters break, carrying the same detail the matching contract revert * carries so a creation form can point at the offending field. */ type LaunchpadCreateParamsViolation = { readonly rule: "emptyName"; } | { readonly rule: "emptySymbol"; } | { readonly rule: "tokenInfoTooLong"; readonly field: LaunchpadTokenInfoField; readonly length: number; readonly maximum: number; } | { readonly rule: "deadlineExpired"; readonly deadline: bigint; readonly now: bigint; } | { readonly rule: "zeroInitialBuyRecipient"; } | { readonly rule: "initialBuyRecipientMustBeCreator"; readonly recipient: Address; } | { readonly rule: "tooManyLaunchTaxExemptions"; readonly count: number; readonly maximum: number; } | { readonly rule: "zeroLaunchTaxExemption"; readonly index: number; } | { readonly rule: "duplicateLaunchTaxExemption"; readonly account: Address; } | { readonly rule: "creatorTaxTooHigh"; readonly creatorTaxBps: number; readonly maximum: number; } | { readonly rule: "feeCombinationTooHigh"; readonly against: "curveFee" | "hookFee"; readonly combined: number; readonly maximum: number; } | { readonly rule: "initialBuyFeesConsumeInput"; } | { readonly rule: "creatorInitialBuyLimitExceeded"; readonly tokenOut: bigint; readonly maximum: bigint; } /** * Only reachable through `launchWithHolderFeeSharing`, which derives the recipient itself and * rejects a caller-supplied one. Not a rule about the parameters in isolation: an ordinary launch * may name any recipient it likes. */ | { readonly rule: "holderSharingRequiresZeroCreatorFeeRecipient"; readonly recipient: Address; }; /** Raised when the factory would reject a creation, listing every rule broken. */ declare class LaunchpadInvalidCreateParamsDetailError extends LaunchpadError { readonly violations: readonly LaunchpadCreateParamsViolation[]; constructor(violations: readonly LaunchpadCreateParamsViolation[]); } /** Everything outside `params` the creation rules are checked against. */ interface LaunchpadCreateParamsContext { /** The account that will appear as `creator` — the transaction sender for `createToken`, or the `originalCreator` argument for a `LaunchForwarder` launch. */ readonly creator: Address; /** The resolved `LaunchConfig` for `params.launchConfigId`. */ readonly launchConfig: { readonly supply: bigint; readonly curveFeeBps: bigint; }; /** The resolved `QuoteTokenEconomics` for `params.quoteToken`. */ readonly quoteTokenEconomics: { readonly phantomQuote: bigint; readonly graduationThreshold: bigint; }; /** `factory.feePolicy().hookFeeBps`, which shares the combined-tax ceiling with the curve fee. */ readonly hookFeeBps: number; /** `factory.maxCreatorTaxBps()`. */ readonly maxCreatorTaxBps: number; /** `factory.maxCreatorInitialBuyBps()`. */ readonly maxCreatorInitialBuyBps: number; /** Chain time to check `params.deadline` against. Omit to skip the deadline rule. */ readonly now?: bigint; } /** * The launch tax exemption set the factory builds, in `_buildExemptions`' own order. * * The creator is always exempt; the creator fee recipient and the initial buy recipient are added * only when they differ from what is already in the set (and the latter only when there actually is * an initial buy). Callers rarely need this directly — it exists because the duplicate rule is * checked against the *whole* set, so passing the creator's own address in * `launchTaxExemptions` is a revert, not a no-op. */ declare function launchpadLaunchTaxExemptions(params: Pick, creator: Address): readonly Address[]; /** * Tokens a creator's atomic initial buy would receive, priced against the *fresh* curve. * * Mirrors `_validateInitialBuy`, which quotes against `(phantomQuote, supply)` rather than any live * reserve — at creation the curve has not traded yet, so those are the reserves. The buy pays the * curve fee and creator tax but never a snipe tax, because the creator is exempt by construction. * * Returns `undefined` when the fees would consume the whole input, which the factory rejects. */ declare function launchpadInitialBuyTokenOut(quoteInRaw: bigint, curveFeeBps: bigint, creatorTaxBps: number, supply: bigint, phantomQuote: bigint, graduationThreshold: bigint): bigint | undefined; /** * Lists every creation rule `params` breaks, or an empty array when the factory would accept them. * * Only the rules that are a pure function of the parameters and the resolved config live here. The * ones that depend on live chain state — `deniedCreators`, `launchEnabled`/`whitelistedLaunchers`, * `usedSalt`, the dependency wiring, `expectedEconomics` matching the current template, and the * quote token's approval — stay with the action layer, which has to read them anyway. * * Every rule is collected rather than thrown on first failure, so a creation form can mark all of * its bad fields in one pass instead of one revert per round trip. Byte lengths are UTF-8, matching * `bytes(...).length` on chain: a name of emoji or CJK text can pass a naive `.length <= 64` check * and still revert. */ declare function launchpadCreateParamsViolations(params: LaunchpadCreateTokenParams, context: LaunchpadCreateParamsContext): readonly LaunchpadCreateParamsViolation[]; /** Throws {@link LaunchpadInvalidCreateParamsDetailError} when the factory would reject `params`. */ declare function assertLaunchpadCreateParams(params: LaunchpadCreateTokenParams, context: LaunchpadCreateParamsContext): void; /** The ten values `expectedEconomics` commits to, drawn from the three governed config layers. */ interface LaunchpadEconomicsCommitment { readonly phantomQuote: bigint; readonly graduationThreshold: bigint; readonly supply: bigint; readonly curveFeeBps: bigint; readonly poolFee: number; readonly tickSpacing: number; readonly protocolFeeShareBps: number; readonly buybackBurnBps: number; readonly hookFeeBps: number; readonly maxInternalPriceImpactBps: number; } /** * Reproduces `EconomicsHash.hash` for `expectedEconomics`. * * Passing the result commits the creation to one exact economics template: if governance changes * any of the ten values between building the transaction and mining it, the creation reverts * instead of launching against terms the creator never saw. Passing `bytes32(0)` instead — see * {@link UNCHECKED_ECONOMICS} — opts out of that protection entirely, which the contract explicitly * allows. */ declare function launchpadEconomicsHash(commitment: LaunchpadEconomicsCommitment): Hex; /** Opt out of the economics-change guard. The contract skips the check entirely for `bytes32(0)`. */ declare const UNCHECKED_ECONOMICS: Hex; /** * Builds `expectedEconomics` from the deployment's own pinned config layers. * * Convenience over {@link launchpadEconomicsHash} for the common case; a caller that has just read * `validateAndResolve` and `feePolicy()` live should hash those values instead, since this uses the * pinned copies. */ declare function launchpadEconomicsHashFromDeployment(context: Pick, input: { readonly quoteToken: Address; readonly launchConfigId: bigint; }): Hex; /** What a creation will produce, previewed before it is sent. */ interface CreateTokenPreview { readonly creator: Address; readonly quoteToken: Address; readonly launchConfigId: bigint; readonly salt: Hex; /** Quote the factory will pull for the atomic initial buy; `0` when there is none. */ readonly initialBuyQuoteRaw: bigint; /** Tokens that initial buy is expected to yield, priced against the fresh curve. */ readonly initialBuyTokenOut: bigint; /** Launch fee the factory will pull, in `launchFeeToken`. Currently `0` on every deployment. */ readonly launchFeeRaw: bigint; /** Predicted addresses, when the deployer was consulted. Confirm against `TokenCreated`. */ readonly predicted?: PredictedLaunchpadToken; /** * The initial buy takes the whole initially sellable supply, so RC2 graduates the launch inside * this same creation. When true, do not expect the new launch to be `notGraduated` — read * `getGraduation` from the receipt's state rather than assuming. */ readonly graduatesOnCreate: boolean; } /** * Predicts the CREATE2 addresses a creation will produce, without sending anything. * * A salt is single-use per creator, so a prediction is invalidated by any launch that consumes the * same salt — check `factory.usedSalt(creator, salt)` before relying on one. The prediction is also * only a preview: `TokenCreated` remains the sole authority that a launch happened. */ declare function predictLaunchpadAddresses(context: LaunchpadWriteActionContext, params: LaunchpadCreateTokenParams, creator: Address): Promise; /** * Returns the contract the creator must approve for a given creation entry point. * * The two entry points genuinely differ, and RC2 changed which is which. `createToken` is pulled by * the **factory**. `launchAndBuy` is pulled by the **forwarder**: RC2 made the forwarder collect the * exact quote and launch-fee amounts from its caller, approve the factory for the duration of the * call, then revoke that approval and refund any residue. Under RC1 the forwarder was a pure * pass-through and the factory was the spender for both paths, so an integration carried over from * RC1 approves the wrong contract and reverts on an allowance the user believes they granted. */ declare function launchpadCreationSpender(deployment: LaunchpadWriteActionContext["deployment"], entryPoint: "createToken" | "launchAndBuy"): Address; /** * Prepares a direct `LaunchFactory.createToken`. * * The connected account becomes the launch's permanent `originalCreator`, is automatically exempt * from the snipe tax, and is the account the factory pulls the launch fee and initial buy from. */ declare function prepareCreateToken(context: LaunchpadWriteActionContext, params: LaunchpadCreateTokenParams): Promise>; /** * Prepares an atomic launch-and-buy through the official forwarder. * * The forwarder preserves creator identity: it calls `launchTokenFor(params, msg.sender)`, so the * account that calls the forwarder — not the forwarder itself — becomes `originalCreator`. * * **The allowance goes to the forwarder, not the factory.** RC2 made the forwarder pull the exact * quote and launch-fee amounts from its caller, hold a temporary factory approval only for the * duration of the call, revoke it, and refund anything unspent. This is the reverse of RC1, where * the forwarder was a pass-through and the factory pulled directly from the creator. Use * {@link launchpadCreationSpender} rather than hard-coding either address. * * Encoded against the `HolderAwareLaunchForwarder` ABI, which the 2026-09-07 rotation made the * active one. `launchAndBuy(CreateTokenParams)` kept its exact signature across that rotation, so * the same calldata would still be valid for the retired forwarder — but that one can no longer * reach the factory's trusted entry point, so there is nothing to point it at. */ declare function prepareLaunchAndBuy(context: LaunchpadWriteActionContext, params: LaunchpadCreateTokenParams): Promise>; declare const HOLDER_DISTRIBUTOR_ADAPTER_V1_INIT_DATA: Hex; /** * Encodes the initialization payload for a given adapter version. * * The factory checks `initializationData` is exactly 32 bytes decoding to its own * `ADAPTER_VERSION`, so this is the whole payload for every version of the current adapter shape. * Pair it with `getLaunchpadHolderAdapterVersion` rather than pinning a number, and a factory * upgraded to a later adapter keeps working. */ declare function launchpadHolderInitializationData(adapterVersion: bigint): Hex; /** What a holder-sharing creation will produce, on top of the ordinary creation preview. */ interface HolderSharingCreateTokenPreview extends CreateTokenPreview { /** * The distributor the forwarder will create and install as `creatorFeeRecipient`. * * Derived from `(creator, salt)` alone — deliberately not from the launch token, which cannot be * known first because the token address depends on this distributor through * `creatorFeeRecipient`. Safe to show before signing, but reconcile against the receipt's * `HolderSharingLaunchCreated` afterwards. */ readonly distributor: Address; /** The initialization payload forwarded to the distributor factory, unchanged. */ readonly distributorInitializationData: Hex; } /** * Predicts the distributor a holder-sharing launch by `creator` with `salt` will produce. * * Note what it is *not* keyed by: the launch token. The distributor has to be predictable before * the token exists, because it becomes the token's `creatorFeeRecipient` and therefore feeds into * the token's own CREATE2 address. Salts are single-use per creator, so this prediction is * invalidated by any launch that consumes the same one. */ declare function predictLaunchpadHolderDistributor(context: LaunchpadActionContext, input: { readonly creator: Address; readonly salt: Hex; }, options?: LaunchpadReadOptions): Promise
; /** The distributor registered for a launch token, or the zero address for an ordinary launch. */ declare function getLaunchpadHolderDistributor(context: LaunchpadActionContext, token: Address, options?: LaunchpadReadOptions): Promise
; /** * Whether the registry recognises an address as one of its own distributors. * * Worth checking before labelling anything in a UI as an official holder distributor: any launch * may nominate an arbitrary `creatorFeeRecipient`, and one that merely looks like a distributor is * not one. */ declare function isLaunchpadHolderDistributor(context: LaunchpadActionContext, distributor: Address, options?: LaunchpadReadOptions): Promise; /** * Prepares an atomic Holder Fee Sharing launch through `launchWithHolderFeeSharing`. * * One transaction creates the per-launch distributor, installs it as the launch's * `creatorFeeRecipient`, creates the token and curve, and verifies every binding. Any failure among * those reverts the whole thing, so there is no partially created launch to clean up. * * **`creatorFeeRecipient` must be the zero address.** The forwarder derives the recipient itself * and rejects a caller-supplied one outright — predicting the distributor and passing it in, the * intuitive thing to try, is exactly what `InvalidCreatorFeeRecipient` is there to stop. The SDK * refuses before simulating so the mistake is legible. * * The allowance goes to the forwarder, as with {@link prepareLaunchAndBuy}. * * Requires a deployment with a holder distributor factory; without one this throws before touching * the network, since Holder Fee Sharing is an optional integration rather than part of the core. */ declare function prepareLaunchWithHolderFeeSharing(context: LaunchpadWriteActionContext, params: LaunchpadCreateTokenParams, options?: { readonly distributorInitializationData?: Hex; }): Promise>; /** Everything a trade needs about its launch, resolved once so a trade costs one round of reads. */ interface ResolvedTradeTarget { readonly curve: Address; readonly quoteToken: Address; readonly curveState: LaunchpadCurveState; } /** Quotes a buy locally against freshly read curve state, including the boundary partial fill. */ declare function quoteLaunchpadBuy(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly quoteInRaw: bigint; readonly tokenRecipient: Address; readonly minTokenOut?: bigint; }): Promise; /** * Prepares a curve buy. * * Two V2-specific traps this handles for the caller. The allowance goes to the **curve**, not the * factory — the curve pulls the quote itself. And the snipe tax is resolved against * `tokenRecipient`, so a UI buying on someone else's behalf must pass the real recipient or it will * quote the wrong rate and set a `minTokenOut` the trade cannot meet. * * The allowance is checked against `quoteSpent`, which on a buy that reaches the graduation * boundary is below the offered amount — approving the offer would over-approve, and the curve * refunds the difference atomically anyway. */ declare function prepareLaunchpadBuy(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly quoteInRaw: bigint; readonly slippage: Slippage; readonly deadline: bigint; /** Defaults to the connected account. Determines the snipe tax, so pass it explicitly when buying for someone else. */ readonly tokenRecipient?: Address; /** `bytes32(0)` for no attribution. A non-zero id must exist on chain or the trade reverts. */ readonly partnerId?: Hex; }): Promise>; /** Quotes a sell locally against freshly read curve state. */ declare function quoteLaunchpadSell(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly tokenIn: bigint; }): Promise; /** * Prepares a curve sell. * * `minQuoteOutRaw` is compared on chain against the seller's **net** proceeds, not the curve's * gross output, so the floor is derived from the net — deriving it from the gross would set a bound * the trade can never clear. A sell never pays snipe tax. */ declare function prepareLaunchpadSell(context: LaunchpadWriteActionContext, input: { readonly token: Address; readonly tokenIn: bigint; readonly slippage: Slippage; readonly deadline: bigint; /** Defaults to the connected account. */ readonly quoteRecipient?: Address; readonly partnerId?: Hex; }): Promise>; /** What an ERC-20 approval will grant. */ interface ApprovalPreview { readonly asset: Address; readonly spender: Address; readonly amount: bigint; } /** * Prepares an ERC-20 approval. * * `spender` has no safe default in V2 and is therefore required: trading is pulled by the token's * own **curve**, while creation (including the forwarder path) is pulled by the **factory**. * Defaulting to either one would silently produce a working approval for one flow and a reverting * one for the other. */ declare function prepareApproveErc20(context: LaunchpadWriteActionContext, input: { readonly asset: Address; readonly spender: Address; readonly amount: bigint; }): Promise>; declare class InvalidLaunchpadChainConfigError extends Error { readonly field: string; constructor(field: string, message: string); } /** Validates, normalizes, and freezes a caller-supplied chain configuration. */ declare function defineLaunchpadChain(input: LaunchpadChainConfig): Readonly; /** Normalizes an EVM token address while preserving its chain-scoped identity. */ declare function defineLaunchpadTokenId(input: LaunchpadTokenId): Readonly; /** Creates a chain-scoped, ABI-neutral Launchpad client around caller-provided adapters. */ declare function createLaunchpadClient(config: LaunchpadClientConfig): LaunchpadClient; declare class UnsupportedLaunchpadCapabilityError extends Error { readonly chainId: number; readonly capability: LaunchpadWriteRequest["requiredCapability"]; constructor(chainId: number, capability: LaunchpadWriteRequest["requiredCapability"]); } /** Raw `LaunchFactory.getLaunchedToken` tuple, as viem returns it (named, never positional). */ interface RawLaunchpadLaunchRecord { readonly token: Address; readonly curve: Address; readonly originalCreator: Address; readonly creatorFeeRecipient: Address; readonly quoteToken: Address; readonly launchConfigId: bigint; readonly economicsHash: Hex; readonly buybackEnabled: boolean; readonly creatorTaxBps: number; readonly hookFeeBps: number; readonly protocolFeeShareBps: number; readonly buybackBurnBps: number; readonly maxInternalPriceImpactBps: number; readonly tickSpacing: number; readonly phantomQuote: bigint; readonly protocolFeeRecipient: Address; } declare class InvalidLaunchpadStateError extends Error { readonly field: string; constructor(field: string, message: string); } /** * Converts a raw launch record, rejecting the zero-token record the factory returns for an address * it never launched. * * The factory's mapping getter yields a zero-filled struct rather than reverting, so without this * check an arbitrary ERC-20 would read back a plausible-looking record whose `curve` is the zero * address — and every subsequent call would then target address zero. */ declare function toLaunchpadLaunchRecord(raw: RawLaunchpadLaunchRecord): LaunchpadLaunchRecord; /** Maps `GraduationStatus`'s ordinal onto its stable name. */ declare function toLaunchpadGraduationStatus(status: number): LaunchpadGraduationStatus; /** Converts the five-value `graduations(token)` tuple into a named record. */ declare function toLaunchpadGraduationRecord(raw: { readonly status: number; readonly sweptAt: bigint; readonly tokenAmount: bigint; readonly quoteAmount: bigint; readonly positionId: bigint; }): LaunchpadGraduationRecord; /** * Assembles a curve state from the slots read off the curve, deriving the pricing reserves and the * graduation boundary the same way `BondingCurveState` does. * * Every input must come from one block: mixing heights produces reserves that never existed. */ declare function toLaunchpadCurveState(input: { readonly curve: Address; readonly supply: bigint; readonly phantomQuote: bigint; readonly graduationThreshold: bigint; readonly curveFeeBps: number; readonly creatorTaxBps: number; readonly snipeTax: { readonly startBps: number; readonly durationSeconds: number; }; readonly trackedTokens: bigint; readonly trackedQuote: bigint; readonly quoteFeeBalance: bigint; readonly creatorTaxBalance: bigint; readonly graduated: boolean; readonly launchedAt: bigint; }): LaunchpadCurveState; /** Arc Mainnet chain id. */ declare const arcMainnetChainId = 5042; /** * Arc Mainnet **Production V2** deployment, `arc-mainnet-v1` (core deployed at block 19588932). * * Built from the same sources as `arc-testnet-rc2`, which is checked rather than assumed: the two * factories have byte-identical runtime code apart from seven immutable slots holding their * respective `feeEscrow` and `partnerRegistry` addresses — 140 bytes out of 22,632. The generated * ABIs therefore apply unchanged, and `MemeHook.partnerLaunchInputSettled`, the getter RC2 added, * answers here too. * * **Live.** Public launch is open (`factory.launchEnabled() == true`) and the operators have run a * create-with-initial-buy, a buy and a sell against it; the end-to-end graduation path has not been * exercised. Every value below was read live from `https://rpc.arc-scan.org` rather than transcribed * from a manifest. * * On 2026-09-08 the deployment rotated onto the Holder-aware forwarder and bound a holder * distributor factory to it, so the last structural difference from the testnet is gone. One * difference remains and it matters before switching an integration over: **USDC is the only quote * token.** tUSDG is a testnet faucet token and does not exist here, so an integration that * hard-codes it has no tradable asset. USDC is an Arc system precompile, which is also why this * deployment cannot be exercised on a local fork. */ declare const arcMainnetLaunchpadDeployment: Readonly; /** Arc Testnet chain id. Testnet-only; never treated as a production default. */ declare const arcTestnetChainId = 5042002; /** * Explicitly named Arc Testnet **Production V2** deployment, `arc-testnet-rc2` (deployed * 2026-09-05, public launch enabled in the same rollout, forwarder rotated 2026-09-07). * * This is a development configuration, not a production default: it is deliberately excluded from * `launchpadDeploymentRegistry`, and consumers must opt in by name. Callers should still run * `verifyLaunchpadDeployment` and allow environment overrides rather than trusting these addresses * outright — the contract repository redeploys this environment freely. * * **RC2 replaces RC1 wholesale.** Every contract was redeployed, tUSDG included, so no RC1 address * survives and no RC1 launch, curve, pool, partner ledger or escrow balance carries over. State * from the two deployments must never be merged; key anything you persist by * {@link LaunchpadDeployment.contractVersion}. The economics are unchanged from RC1 — same phantom * quote, graduation threshold, supply, fee policy and snipe tax — so a diff of this file is almost * entirely addresses. The behavioural changes RC2 does carry (the forwarder now pulls funds itself, * graduation can complete automatically inside a buy, and pool fee sweeps settle partially) are * implemented in the actions rather than here; see * `docs/ai/launchpad-production-v2-migration-gaps.md`. * * Addresses come from * `contracts/production/release/arc-testnet-rc2/deployment-manifest.json`. The runtime code hash and * deployment block were read live against `https://rpc.testnet.arc.io` rather than transcribed: the * manifest publishes neither, and the block was found by bisecting `eth_getCode` against the factory * (first present at `60614952`, absent at `60614951`). */ declare const arcTestnetLaunchpadDeployment: Readonly; /** Typed client configuration, taking one verified chain config so capabilities cannot drift. */ interface LaunchpadFactoryClientConfig { readonly publicClient: PublicClient; readonly walletClient?: WalletClient; readonly chain: LaunchpadChainConfig; } /** * Client bound to one verified Production V2 `LaunchFactory` deployment. * * Reads take a token address and resolve the token's own curve internally. A caller making several * calls for one launch can avoid the repeated lookup by reading the record once * ({@link LaunchpadFactoryClient.getLaunchRecord}) and using the curve-level methods directly. */ interface LaunchpadFactoryClient { readonly deployment: LaunchpadDeployment; readonly chain: LaunchpadChainConfig; isLaunchToken(token: Address, options?: LaunchpadReadOptions): Promise; getCurveAddress(token: Address, options?: LaunchpadReadOptions): Promise
; getLaunchRecord(token: Address, options?: LaunchpadReadOptions): Promise; getTokenState(token: Address, options?: LaunchpadReadOptions): Promise; /** * Reads one curve's full pricing state. * * Takes only the curve address. It used to take a `quoteToken` as well, which was dead weight * once the read started sourcing `graduationThreshold` from the curve itself — and worse than * dead weight, since a pinned quote token is exactly the value that misprices older launches * after governance retunes the template. */ getCurveState(input: { readonly curve: Address; }, options?: LaunchpadReadOptions): Promise; getCurveProgress(token: Address, options?: LaunchpadReadOptions): Promise; getGraduation(token: Address, options?: LaunchpadReadOptions): Promise; getPoolId(token: Address, options?: LaunchpadReadOptions): Promise; getTokenInfo(token: Address, options?: LaunchpadReadOptions): Promise; getErc20Metadata(asset: Address, options?: LaunchpadReadOptions): Promise; getBalance(asset: Address, owner: Address, options?: LaunchpadReadOptions): Promise; getApprovalStatus(input: { readonly asset: Address; readonly owner: Address; readonly requiredAmount: bigint; readonly spender?: Address; }, options?: LaunchpadReadOptions): Promise; isTaxExempt(input: { readonly curve: Address; readonly account: Address; }, options?: LaunchpadReadOptions): Promise; canLaunch(creator: Address, options?: LaunchpadReadOptions): Promise; getLaunchGate(creator: Address, options?: LaunchpadReadOptions): Promise; validateAndResolve(input: { readonly quoteToken: Address; readonly launchConfigId: bigint; }, options?: LaunchpadReadOptions): ReturnType; predictAddresses(params: LaunchpadCreateTokenParams, creator: Address): Promise; prepareCreateToken(params: LaunchpadCreateTokenParams): Promise>; prepareLaunchAndBuy(params: LaunchpadCreateTokenParams): Promise>; /** * Atomic Holder Fee Sharing launch. Requires `params.creatorFeeRecipient` to be the zero * address — the forwarder creates the distributor and installs it itself. */ prepareLaunchWithHolderFeeSharing(params: LaunchpadCreateTokenParams, options?: { readonly distributorInitializationData?: Hex; }): Promise>; /** The distributor registered for a launch token; zero for an ordinary launch. */ getHolderDistributor(token: Address, options?: LaunchpadReadOptions): Promise
; /** Whether the registry recognises this address as one of its own distributors. */ isHolderDistributor(distributor: Address, options?: LaunchpadReadOptions): Promise; /** A holder distributor's bindings and live balances. */ getHolderDistributorState(distributor: Address, options?: LaunchpadReadOptions): Promise; /** One published epoch, with derived expiry flags. */ getHolderEpoch(input: { readonly distributor: Address; readonly epochId: bigint; readonly now?: bigint; }, options?: LaunchpadReadOptions): Promise; /** Whether an account has already claimed a given epoch. */ hasHolderClaimed(input: { readonly distributor: Address; readonly epochId: bigint; readonly account: Address; }, options?: LaunchpadReadOptions): Promise; /** Whether an account is barred from claiming — protocol-owned addresses, mostly. */ isHolderExcluded(input: { readonly distributor: Address; readonly account: Address; }, options?: LaunchpadReadOptions): Promise; /** Whether the distributor project will distribute revenue in this quote asset. */ isHolderQuoteTokenAllowed(quoteToken: Address, options?: LaunchpadReadOptions): Promise; /** * Claims one holder allocation. Anyone may submit it — the payout follows * `allocation.account`, not the sender. */ prepareHolderClaim(input: { readonly distributor: Address; readonly allocation: LaunchpadHolderAllocation; }): Promise>; /** Claims several allocations at once. All-or-nothing. */ prepareHolderClaimMany(input: { readonly distributor: Address; readonly allocations: readonly LaunchpadHolderAllocation[]; }): Promise>; /** Pulls escrowed revenue, vested buyback and harvester proceeds into the distributor. */ prepareHolderHarvest(distributor: Address): Promise>; /** Returns an expired epoch's unclaimed remainder to the unallocated pool. */ prepareHolderRollOver(input: { readonly distributor: Address; readonly epochId: bigint; }): Promise>; /** * Approves an ERC-20 for a spender. * * `spender` is required rather than defaulted: trading is pulled by the token's own **curve** * while creation is pulled by the **factory**, so a default would be silently wrong half the * time. Resolve the curve with {@link LaunchpadFactoryClient.getCurveAddress} first. */ prepareApprove(input: { readonly asset: Address; readonly spender: Address; readonly amount: bigint; }): Promise>; prepareBuy(input: { readonly token: Address; readonly quoteInRaw: bigint; readonly slippage: Slippage; readonly deadline: bigint; readonly tokenRecipient?: Address; readonly partnerId?: Hex; }): Promise>; prepareSell(input: { readonly token: Address; readonly tokenIn: bigint; readonly slippage: Slippage; readonly deadline: bigint; readonly quoteRecipient?: Address; readonly partnerId?: Hex; }): Promise>; prepareGraduate(token: Address): Promise>; prepareCreateGraduatedPool(token: Address): Promise>; getPendingFees(curve: Address, options?: LaunchpadReadOptions): Promise; getClaimableBalance(input: { readonly recipient: Address; readonly asset: Address; }, options?: LaunchpadReadOptions): Promise; getPartnerClaimableBalance(input: { readonly partnerId: Hex; readonly asset: Address; }, options?: LaunchpadReadOptions): Promise; prepareClaim(input: { readonly asset: Address; readonly amount?: bigint; }): Promise>; preparePartnerClaim(input: { readonly partnerId: Hex; readonly asset: Address; }): Promise>; getPartner(partnerId: Hex, options?: LaunchpadReadOptions): Promise; getPartnerPolicy(options?: LaunchpadReadOptions): Promise; getPartnerUsability(partnerId: Hex, options?: LaunchpadReadOptions): Promise; getBuybackVest(token: Address, options?: LaunchpadReadOptions): Promise; getBuybackReleasable(token: Address, options?: LaunchpadReadOptions): Promise; prepareBuybackRelease(token: Address): Promise>; prepareSetBuybackEnabled(input: { readonly token: Address; readonly enabled: boolean; }): Promise>; getEmergencyDistributor(input: { readonly launchToken: Address; readonly quoteToken: Address; }, options?: LaunchpadReadOptions): Promise<{ readonly distributor: Address; readonly deployed: boolean; }>; getEmergencyExitState(distributor: Address, options?: LaunchpadReadOptions): Promise; quoteEmergencyRedeem(input: { readonly distributor: Address; readonly tokenIn: bigint; }): Promise; prepareEmergencyRedeem(input: { readonly distributor: Address; readonly tokenIn: bigint; readonly recipient?: Address; }): Promise>; send(prepared: PreparedLaunchpadTransaction): Promise; wait(hash: Hash, options?: { readonly confirmations?: number; }): Promise; } /** Creates a client bound to one verified deployment. */ declare function createLaunchpadFactoryClient(config: LaunchpadFactoryClientConfig): LaunchpadFactoryClient; /** * `BondingCurveMath.getAmountOut`. Constant-product output for `amountIn` against `(reserveIn, * reserveOut)`, floored — the trader never receives more than the curve actually owes. * * Direction-agnostic: a buy calls this with `(quoteReserve, tokenReserve)`, a sell with * `(tokenReserve, quoteReserve)`. Neither side is ever converted through a fixed-point scale — * unlike V3's `CurveMath`, Production V2 prices entirely in each side's own raw units. */ declare function curveGetAmountOut(amountIn: bigint, reserveIn: bigint, reserveOut: bigint): bigint; /** * `BondingCurveMath.getAmountIn`. Smallest `amountIn` whose forward quote is at least `amountOut`, * ceiled — the trader must never pay less than the curve requires for that output. * * `getAmountOut` and `getAmountIn` are each other's exact algebraic inverse (both derive from the * same `k = reserveIn * reserveOut` relation), so — unlike V3's sell direction — no bisection search * is needed for either side of Production V2's curve. */ declare function curveGetAmountIn(amountOut: bigint, reserveIn: bigint, reserveOut: bigint): bigint; /** * `BondingCurveMath.reservedTokens`. The floor of `trackedTokens` a curve may never sell through — * the Token-side graduation boundary, fixed for the curve's lifetime at construction. * * Larger `phantomQuote` relative to `graduationThreshold` reserves a larger fraction of `supply`: * the phantom quote is virtual liquidity the curve prices against from block zero, so a curve that * leans on more of it must hold back more real tokens to keep the same price path solvent down to * the reserved floor. */ declare function launchpadReservedTokens(supply: bigint, phantomQuote: bigint, graduationThreshold: bigint): bigint; /** * The curve constants fixed at construction (`CurveInitialization`) and never touched by a trade. * Kept separate from {@link LaunchpadCurveLiveState} because `reservedTokens` is derived once from * these and then reused every call, rather than recomputed per trade. */ interface LaunchpadCurveConstants { readonly supply: bigint; readonly phantomQuote: bigint; readonly graduationThreshold: bigint; } /** The four `BondingCurveState` storage slots a trade actually mutates. */ interface LaunchpadCurveLiveState { /** Tokens still held by the curve; decreases on a buy, increases on a sell. Not circulating supply — it also excludes tokens the curve has already swept out as fees. */ readonly trackedTokens: bigint; /** Net quote the curve has taken in from trades, before subtracting pending fees. Only trades and fee sweeps move it — a forced ERC-20 donation to the curve's balance is not tracked. */ readonly trackedQuote: bigint; /** Curve fee and snipe tax collected but not yet swept out to `pendingProtocol`/`pendingCreator`/`pendingPartner`. */ readonly quoteFeeBalance: bigint; /** Creator tax collected but not yet swept to `pendingCreatorTax`. Subset of `quoteFeeBalance`'s role, tracked separately because creator tax is never split with the platform. */ readonly creatorTaxBalance: bigint; } /** * `IBondingCurveState`'s complete pricing-relevant state: the immutable constants plus the four * live slots, with `reservedTokens` already derived. Build it with {@link launchpadCurveState} * rather than by hand — constructing a state with an inconsistent `reservedTokens` would price * against a boundary the real curve never had. */ interface LaunchpadCurveMathState extends LaunchpadCurveConstants, LaunchpadCurveLiveState { readonly reservedTokens: bigint; } /** * Builds and validates a {@link LaunchpadCurveMathState} from live chain reads. * * Mirrors the checks `BondingCurveState`'s constructor and every trade path implicitly rely on: * `reservedTokens` is in `(0, supply)`, and `phantomQuote + trackedQuote` is enough to cover * `quoteFeeBalance + creatorTaxBalance` — a violation of either is not a pricing edge case, it means * the four live fields were not read from the same block or the deployment constants are wrong, and * {@link curvePricingReserves} would otherwise underflow into a negative `bigint` where Solidity * would have reverted. */ declare function launchpadCurveState(constants: LaunchpadCurveConstants, live: LaunchpadCurveLiveState): Readonly; /** The `(quoteReserve, tokenReserve)` pair every quote is priced against. */ interface LaunchpadCurveReserves { readonly quoteReserve: bigint; readonly tokenReserve: bigint; } /** * `BondingCurveState.pricingReserves`. `quoteReserve` nets pending fees and creator tax out of the * curve's tracked quote — they have already been earned, not principal available to price against — * and adds back `phantomQuote`, the virtual liquidity the curve prices against even when no real * quote has arrived yet. `tokenReserve` is `trackedTokens` unchanged. */ declare function curvePricingReserves(state: LaunchpadCurveMathState): LaunchpadCurveReserves; /** * `BondingCurveState.sellableTokens`. Tokens the curve will still sell before hitting the * graduation boundary; `0` once `trackedTokens` has drained to `reservedTokens`. */ declare function launchpadSellableTokens(state: LaunchpadCurveMathState): bigint; /** * `BondingCurveState.quoteBuyNet`. Tokens received for `netQuoteIn` — quote **after** curve fee, * snipe tax, and creator tax have already been taken out — capped to {@link launchpadSellableTokens}. * * The cap silently truncates rather than throwing: the contract's own view function does the same, * because a UI polling a live quote should see "this now buys the rest of the curve", not an error, * as the remaining supply shrinks toward the trader's request. */ declare function curveQuoteBuyNet(state: LaunchpadCurveMathState, netQuoteIn: bigint): bigint; /** `BondingCurveState.quoteSellGross`. Quote the curve gives up for `tokenIn`, before fee and tax. */ declare function curveQuoteSellGross(state: LaunchpadCurveMathState, tokenIn: bigint): bigint; /** * `BondingCurveState.quoteNetRequiredToBuy`. Net quote (after fee/tax) required to receive exactly * `tokenOut`. * * Throws {@link LaunchpadProtocolConfigurationError}, not {@link LaunchpadInvalidAmountError}, when * `tokenOut` exceeds {@link launchpadSellableTokens} — that is the exact revert selector the * contract's own `quoteNetRequiredToBuy` uses for this case (`InvalidConfiguration`, not * `InvalidAmount`), so a caller pattern-matching on-chain revert data must see the same one here. */ declare function curveQuoteNetRequiredToBuy(state: LaunchpadCurveMathState, tokenOut: bigint): bigint; /** * `BondingCurve.graduationReady`, restricted to the pricing-state half of that check. * * The contract requires two more things before it reports ready, neither of which is part of the * pricing state: `token != address(0)` (the curve's `LauncherToken` has been wired up) and, since * RC2, `!graduated`. Check both separately — `getLaunchpadCurveState` already folds them in, so * prefer `curveState.graduationReady` over calling this directly on a hand-built state. */ declare function launchpadGraduationReady(state: LaunchpadCurveMathState): boolean; /** * `EmergencyDistributor.redeem`'s payout. * * `quoteOut = floor(tokenIn * remainingQuote / supply)`, where `supply` is the launch token's * **live** `totalSupply()` at redemption time — not a snapshot taken at activation, which is what * V3 used. Two consequences follow, and both are intentional protocol behaviour rather than * rounding artefacts: * * - A holder who burns tokens without redeeming permanently increases everyone else's payout per * token, because the denominator shrinks while `remainingQuote` does not. * - The last holder to redeem takes the entire remaining quote, since `tokenIn === supply` makes * the division exact. This is how the contract avoids stranding dust, and why * {@link launchpadIsFinalRedemption} is worth surfacing in a UI. */ declare function launchpadEmergencyRedeemQuoteOut(input: { readonly tokenIn: bigint; readonly supply: bigint; readonly remainingQuote: bigint; }): bigint; /** True when this redemption consumes the entire remaining supply, and so the entire remaining quote. */ declare function launchpadIsFinalRedemption(tokenIn: bigint, supply: bigint): boolean; /** `BondingCurve._feesFromGross`'s three-way split, in raw quote units. */ interface LaunchpadTradeFeeBreakdown { /** What the trader pays (buy) or the curve gives up before fees (sell). */ readonly gross: bigint; /** Curve fee: `curveFeeBps` of `gross`. Always charged, split between platform and creator. */ readonly baseFee: bigint; /** Opening snipe tax: `snipeTaxBps` of `gross`. Only ever non-zero on a buy — sells always pass `snipeTaxBps: 0`. Also split between platform and creator. */ readonly snipeTax: bigint; /** Creator tax: `creatorTaxBps` of `gross`. 100% the creator's; never split with the platform or a partner. */ readonly creatorTax: bigint; /** `baseFee + snipeTax + creatorTax`. */ readonly totalFee: bigint; /** `gross - totalFee`: what reaches the curve reserve (buy) or the trader (sell). */ readonly net: bigint; } /** * `BondingCurve._feesFromGross`. * * A buy passes the live `currentSnipeTaxBps(tokenRecipient)` (see `math/protection.ts`); a sell * always passes `snipeTaxBps: 0` — the contract has no anti-sniper surcharge on the sell side. * `curveFeeBps` and `creatorTaxBps` are the curve's own immutable constants, fixed at creation. * * Throws {@link LaunchpadTradeFeeConsumesInputError} once fees would consume the entire input — * the contract's `totalFee >= gross` check, which V3 had no equivalent of (its worst case still * left `net = 0` and reverted with a *different* reason, `ZeroNetTrade`; this reverts before ever * computing a net amount). */ declare function feesFromGross(input: { readonly gross: bigint; readonly curveFeeBps: number; readonly snipeTaxBps: number; readonly creatorTaxBps: number; }): LaunchpadTradeFeeBreakdown; /** `BondingCurve.FeeAllocation`, plus the pass-through `creatorTax` the event also carries. */ interface LaunchpadFeeAllocation { /** Added to `pendingProtocol`. */ readonly platformNet: bigint; /** Added to `pendingCreator` alongside `creatorTax` (the contract sums them into one pending bucket, even though only `creatorTax` also separately accrues to `pendingCreatorTax`). */ readonly creatorImmediate: bigint; /** Carve-out of `creatorImmediate`'s pre-split gross, added to `pendingBuyback` instead of `pendingCreator` when the launch has buyback enabled. */ readonly buybackBudget: bigint; /** Added to `pendingPartner[partnerId]`. Zero when no partner is attributed or the attributed partner is disabled. */ readonly partnerFee: bigint; /** Passed through unchanged from {@link feesFromGross}; 100% creator's, never split. */ readonly creatorTax: bigint; } /** * `BondingCurve._allocateFees`. * * The one detail easy to get wrong from the percentages alone: **`partnerFee` is cut only from * `baseFee`'s platform share, never from `snipeTax`'s.** The contract computes * `basePlatformGross` and `snipePlatformGross` separately, sums them into `platformGross`, but then * takes the partner's cut from `basePlatformGross` alone — so a partner's effective share of the * *combined* platform take shrinks whenever the snipe tax is non-zero, rather than staying a fixed * fraction of it. * * `creatorTax` never enters this split at all: it bypasses `protocolFeeShareBps` and * `buybackBurnBps` entirely and is added to `creatorImmediate` as a flat pass-through, matching the * contract's `pendingCreator += allocation.creatorImmediate + creatorTax`. * * Throws {@link LaunchpadPartnerError} for `partnerShareBps > maxPartnerShareOfPlatformBps` — the * contract's `PartnerShareTooHigh`. This is a governance-drift guard, not a per-trade one: it fires * only if `PartnerRegistry.partnerPolicy()`'s cap was lowered after a partner's own share was set * above the new cap, since `createPartner`/`setPartnerShare` already enforce the cap at write time. */ declare function allocateLaunchpadFees(input: { readonly baseFee: bigint; readonly snipeTax: bigint; readonly creatorTax: bigint; readonly protocolFeeShareBps: number; readonly partnerShareBps: number; readonly maxPartnerShareOfPlatformBps: number; readonly buybackEnabled: boolean; readonly buybackBurnBps: number; }): LaunchpadFeeAllocation; /** The curve's own immutable fee constants, needed on every trade quote. */ interface LaunchpadCurveFeeConfig { readonly curveFeeBps: number; readonly creatorTaxBps: number; } /** Full local reproduction of `BondingCurve._buyExactIn`'s pricing and fee math. */ interface LaunchpadBuySimulation { /** Tokens the trade actually receives; equals {@link launchpadSellableTokens} when {@link isPartialFill}. */ readonly tokenOut: bigint; /** * Gross quote actually spent — at most `quoteInRaw`, and usually strictly less when * {@link isPartialFill}. Not *always* less: RC2 clamps the boundary spend to the offer, so an * offer that exactly covers the final fill spends all of it and refunds nothing. */ readonly quoteSpent: bigint; /** `quoteInRaw - quoteSpent`. The contract refunds this atomically in the same transaction. */ readonly refund: bigint; /** Fees computed against `quoteSpent` (not the original `quoteInRaw`) — the contract recomputes them at the boundary rather than pro-rating the original quote. */ readonly fees: LaunchpadTradeFeeBreakdown; /** * True once the buy would have bought more than {@link launchpadSellableTokens} and was truncated * to it. * * Under RC2 this also predicts a lifecycle change: taking the whole sellable supply empties the * curve, so the curve calls back into the factory and graduates the launch **in this same * transaction**. A caller that shows post-trade state should re-read the graduation status after * a partial fill rather than assuming the launch is still trading. */ readonly isPartialFill: boolean; } /** * `BondingCurve._buyExactIn`'s pricing and fee logic, minus the parts that are not pricing at all: * `_requireTradingOpen`'s gates (deadline, `graduated`, token/tax-exemption initialization), * `tokenRecipient` validity, and the actual asset transfers. Those stay the action layer's job. * * `snipeTaxBps` must be the caller's own `currentSnipeTaxBps(tokenRecipient)` from * `math/protection.ts` — this function does not compute it, because doing so here would require * threading `tokenRecipient` and `now` through a "pricing" function that otherwise depends on * nothing but curve state and fee constants. * * Throws {@link LaunchpadSlippageError} for both the ordinary and the partial-fill minimum-output * checks, {@link LaunchpadTradeFeeConsumesInputError} when fees would consume the entire input (in * the partial-fill branch this mirrors the contract's own `TradeFeeConsumesInput(quoteInRaw, * quoteInRaw)` — both revert arguments are the original gross, not any intermediate total fee, which * looks like a copy-paste of the non-boundary revert but is what the deployed contract actually * does), and {@link LaunchpadInvalidAmountError} for a zero result. */ declare function simulateLaunchpadBuyExactIn(state: LaunchpadCurveMathState, feeConfig: LaunchpadCurveFeeConfig, input: { readonly quoteInRaw: bigint; readonly snipeTaxBps: number; readonly minTokenOut: bigint; }): LaunchpadBuySimulation; /** Full local reproduction of `BondingCurve._sellExactIn`'s pricing and fee math. */ interface LaunchpadSellSimulation { /** Quote before fees — `getAmountOut(tokenIn, tokenReserve, quoteReserve)`. */ readonly grossQuoteOut: bigint; /** Net quote the trader receives: `grossQuoteOut` minus fees. */ readonly quoteOut: bigint; readonly fees: LaunchpadTradeFeeBreakdown; } /** * `BondingCurve._sellExactIn`'s pricing and fee logic, minus `_requireTradingOpen`'s gates and the * actual transfers — same split of responsibility as {@link simulateLaunchpadBuyExactIn}. * * A sell always prices with `snipeTaxBps: 0` — there is no anti-sniper surcharge on the sell side — * so unlike the buy direction this never needs a caller-supplied snipe tax rate. * * Throws {@link LaunchpadSlippageError} below `minQuoteOutRaw`, and * {@link LaunchpadInsufficientQuoteReserveError} when the payout would exceed the curve's real * (non-phantom) quote reserve — a case a naive constant-product calculation alone would not catch, * because `phantomQuote` inflates `quoteReserve` beyond what the curve can actually pay out. */ declare function simulateLaunchpadSellExactIn(state: LaunchpadCurveMathState, feeConfig: LaunchpadCurveFeeConfig, input: { readonly tokenIn: bigint; readonly minQuoteOutRaw: bigint; }): LaunchpadSellSimulation; /** * `SnipeTax.DECAY_SHIFT_RANGE`. The tax halves, at minimum, every `durationSeconds / * DECAY_SHIFT_RANGE` seconds — a right shift by 1 bit per that many seconds elapsed, not a linear * ramp. `startBps` is capped at `BPS` (10,000) deployment-wide, so a shift of 14 always reaches 0 * before `elapsedSeconds` can reach `durationSeconds` from below. */ declare const SNIPE_TAX_DECAY_SHIFT_RANGE = 14; /** * `SnipeTax.currentBps`. The opening snipe tax, decaying from `startBps` to `0` by * `elapsedSeconds === durationSeconds`. * * A right-shift decay rather than V3's discrete per-block ladder: Production V2 has no block-offset * concept in its fee schedule at all, so this is not a replacement for `tradeFeeBpsAt` — the * six-step ladder, its permanent post-ladder floor, and the "creation block charges 100%" trading * gate are all gone. This can reach exactly `0` bps while the curve is still open, unlike V3 where * the base fee always applied. */ declare function snipeTaxCurrentBps(startBps: number, durationSeconds: number, elapsedSeconds: bigint): number; /** * `BondingCurve.currentSnipeTaxBps`. Combines the decay curve with the curve's per-token exemption * set — the two are checked together on chain, in this order, so a caller cannot get a different * answer by evaluating them separately in the other order (an exempt but non-zero-`startBps` * recipient must read `0`, never the undecayed `startBps`). * * `isExempt` must come from the curve's own `isLaunchTaxExempt(tokenRecipient)`, keyed on the * **token recipient**, not the transaction sender or payer — a router or relayer submitting on a * trader's behalf must not cause the trader to inherit the router's exemption or lack of one. See * `docs/PRODUCTION_FRONTEND_INTEGRATION.md` section 3 and section 6.2 of the contract design doc. */ declare function currentLaunchpadSnipeTaxBps(params: { readonly snipeTax: LaunchpadSnipeTaxConfig; readonly launchedAt: bigint; readonly now: bigint; readonly isExempt: boolean; }): number; /** Hard ceiling on caller-supplied slippage. Anything above this is rejected outright. */ declare const MAX_SLIPPAGE_BPS = 5000; /** Default deadline horizon: ten minutes from the reference chain time. */ declare const DEFAULT_DEADLINE_SECONDS = 600n; declare class InvalidSlippageError extends Error { readonly bps: number; constructor(bps: number, message: string); } declare class InvalidDeadlineError extends Error { constructor(message: string); } /** Validates a slippage tolerance against the 0..50% range. */ declare function assertSlippage(slippage: Slippage): number; /** * Applies slippage to a quoted output, rounding **down** so the on-chain minimum is never more * optimistic than the quote. Rejects a zero expected output, because a zero `minOut` would * disable the contract's own slippage guard. */ declare function applySlippageToMinimumOut(expectedOut: bigint, slippage: Slippage): bigint; /** * Applies slippage to a quoted **input**, rounding **up**, producing the `quoteInMax` ceiling for * an exact-output buy. * * The mirror image of {@link applySlippageToMinimumOut}, and the reason the factory can express a "Max * Sold" control at all: `QuoteLaunchFactoryV3.buy` takes `quoteInMax` alongside `minTokenOut`, so * the trader names the tokens they want and caps what they will pay for them. Rounding up here is * what makes the cap a real tolerance rather than a quote that reverts on the first wei of curve * movement. */ declare function applySlippageToMaximumIn(expectedIn: bigint, slippage: Slippage): bigint; /** * Builds a transaction deadline from a reference chain timestamp. The reference must come from a * block, not the client clock, because the factory compares against `block.timestamp`. */ declare function toDeadline(referenceTimestamp: bigint, seconds?: bigint): bigint; /** Rounds up `x * y / denominator`. */ declare function mulDivUp(x: bigint, y: bigint, denominator: bigint): bigint; /** Raised when on-chain state contradicts a registered deployment. */ declare class LaunchpadDeploymentVerificationError extends Error { readonly field: string; readonly expected: string; readonly actual: string; constructor(field: string, expected: string, actual: string); } /** What a verification actually checked, so a caller can log it rather than trusting a bare boolean. */ interface LaunchpadVerificationReport { readonly chainId: number; readonly factory: Address; readonly factoryRuntimeCodeHash: `0x${string}`; readonly checkedQuoteTokens: readonly Address[]; readonly checkedLaunchConfigIds: readonly bigint[]; } /** * Proves a registered deployment matches on-chain state before anything is trusted. * * Verifies three separable things, because they fail for different reasons: * * 1. **Identity** — the factory's runtime code hash. Catches a wrong or re-deployed address. * 2. **Wiring** — every module address the factory reports, plus the hook's own view of the V4 * PoolManager. Catches a half-configured deployment, which V2 makes easy to produce since the * dependencies are set individually after construction rather than in the constructor. * 3. **Economics** — the fee policy, partner policy, snipe tax, launch fee, creator ceilings, and * every pinned quote token and launch config. These are mutable governance state, so a mismatch * usually means the pinned record has drifted rather than that the deployment is wrong. * * The economics checks are the reason this must run against a live chain rather than being folded * into `defineLaunchpadDeployment`: governance can move them at any time with no redeployment and * no change to any address. */ declare function verifyLaunchpadDeployment(publicClient: PublicClient, deployment: LaunchpadDeployment): Promise; export { type ApprovalPreview, type BuyQuote, type BuybackReleasePreview, type ClaimPreview, type CreateTokenPreview, DEFAULT_DEADLINE_SECONDS, type EmergencyRedeemQuote, ForgedPreparedTransactionError, type GraduationStepPreview, HOLDER_DISTRIBUTOR_ADAPTER_V1_INIT_DATA, type HolderSharingCreateTokenPreview, InvalidDeadlineError, InvalidLaunchpadChainConfigError, InvalidLaunchpadDeploymentError, InvalidLaunchpadReadInputError, InvalidLaunchpadStateError, InvalidSlippageError, LAUNCHPAD_EMERGENCY_EXIT_DELAY_SECONDS, LaunchpadAccountingInvariantError, type LaunchpadActionContext, type LaunchpadAdapterRegistry, LaunchpadApprovalRequiredError, type LaunchpadApprovalStatus, type LaunchpadAssetRef, type LaunchpadAutoGraduationFailedEvent, type LaunchpadBuySimulation, type LaunchpadBuybackSettledEvent, type LaunchpadBuybackVaultEvent, type LaunchpadBuybackVest, type LaunchpadCapability, type LaunchpadChainConfig, type LaunchpadChainRegistry, type LaunchpadClient, type LaunchpadClientConfig, type LaunchpadContractAdapter, type LaunchpadContracts, type LaunchpadCreateParamsContext, type LaunchpadCreateParamsViolation, type LaunchpadCreateTokenParams, LaunchpadCreatorDeniedError, type LaunchpadCurveConstants, type LaunchpadCurveFeeConfig, type LaunchpadCurveFeesSweptEvent, type LaunchpadCurveLiveState, type LaunchpadCurveMathState, type LaunchpadCurvePendingFees, type LaunchpadCurveProgress, type LaunchpadCurveReserves, type LaunchpadCurveState, LaunchpadDeadlineExpiredError, type LaunchpadDeployment, type LaunchpadDeploymentRegistry, LaunchpadDeploymentVerificationError, type LaunchpadEconomics, type LaunchpadEconomicsCommitment, LaunchpadEconomicsHashMismatchError, type LaunchpadEmergencyDistributorEvent, LaunchpadEmergencyExitNotReadyError, type LaunchpadEmergencyExitState, type LaunchpadErc20Metadata, LaunchpadError, type LaunchpadFactoryClient, type LaunchpadFactoryClientConfig, type LaunchpadFeeAllocatedEvent, type LaunchpadFeeAllocation, type LaunchpadFeeEscrowBalance, type LaunchpadFeeEscrowEvent, type LaunchpadFeePolicy, LaunchpadGovernanceDelayError, type LaunchpadGraduationEvent, type LaunchpadGraduationProgress, type LaunchpadGraduationRecord, type LaunchpadGraduationStatus, type LaunchpadHolderAllocation, type LaunchpadHolderDistributorEvent, type LaunchpadHolderDistributorState, type LaunchpadHolderEpoch, type LaunchpadHolderSharingEvent, type LaunchpadHolderSweepPreview, LaunchpadInsufficientBalanceError, LaunchpadInsufficientQuoteReserveError, LaunchpadInvalidAmountError, LaunchpadInvalidCreateParamsDetailError, LaunchpadInvalidCreateParamsError, type LaunchpadLaunchConfig, type LaunchpadLaunchConfigEvent, type LaunchpadLaunchGate, LaunchpadLaunchNotPermittedError, type LaunchpadLaunchRecord, LaunchpadNoPendingProposalError, LaunchpadNothingToClaimError, type LaunchpadPartnerConfig, type LaunchpadPartnerEpochAccounting, LaunchpadPartnerError, type LaunchpadPartnerEscrowBalance, type LaunchpadPartnerPolicy, type LaunchpadPartnerPolicySnapshot, type LaunchpadPartnerUsability, type LaunchpadPendingCreatorRecipientChange, LaunchpadPhaseUnavailableError, type LaunchpadPoolFeeEvent, type LaunchpadPoolSweepState, LaunchpadProtocolConfigurationError, type LaunchpadQuoteToken, type LaunchpadQuoteTokenConfig, type LaunchpadReadContext, type LaunchpadReadOptions, type LaunchpadReadRequest, type LaunchpadReceiptEvents, type LaunchpadSellSimulation, LaunchpadSlippageError, type LaunchpadSnipeTaxChargedEvent, type LaunchpadSnipeTaxConfig, type LaunchpadSocials, type LaunchpadTokenCreatedEvent, type LaunchpadTokenId, type LaunchpadTokenInfo, type LaunchpadTokenInfoField, type LaunchpadTokenState, type LaunchpadTradeAvailability, type LaunchpadTradeBlockedReason, type LaunchpadTradeEvent, type LaunchpadTradeFeeBreakdown, LaunchpadTradeFeeConsumesInputError, LaunchpadTradingClosedError, type LaunchpadTransactionResult, LaunchpadTransferFailedError, LaunchpadUnauthorizedError, LaunchpadUnknownTokenError, type LaunchpadVerificationReport, type LaunchpadWriteActionContext, type LaunchpadWriteContext, type LaunchpadWriteRequest, MAX_COMBINED_BASE_AND_CREATOR_TAX_BPS, MAX_DESCRIPTION_BYTES, MAX_EXTRA_LAUNCH_TAX_EXEMPTIONS, MAX_LOGO_BYTES, MAX_NAME_BYTES, MAX_SLIPPAGE_BPS, MAX_SOCIAL_BYTES, MAX_SYMBOL_BYTES, MissingWalletClientError, NO_PARTNER_ID, type PredictedLaunchpadToken, PreparedAccountMismatchError, type PreparedLaunchpadTransaction, type PreparedLaunchpadTransactionContext, type RawLaunchpadLaunchRecord, SNIPE_TAX_DECAY_SHIFT_RANGE, type SellQuote, type Slippage, UNCHECKED_ECONOMICS, UnpinnableBlockTagError, UnsupportedLaunchpadCapabilityError, WrongWalletChainError, allocateLaunchpadFees, applySlippageToMaximumIn, applySlippageToMinimumOut, arcMainnetChainId, arcMainnetLaunchpadDeployment, arcTestnetChainId, arcTestnetLaunchpadDeployment, assertLaunchpadCanSpend, assertLaunchpadCreateParams, assertSlippage, canLaunchpadCreatorLaunch, createLaunchpadClient, createLaunchpadFactoryClient, createdLaunchAddresses, currentLaunchpadSnipeTaxBps, curveGetAmountIn, curveGetAmountOut, curvePricingReserves, curveQuoteBuyNet, curveQuoteNetRequiredToBuy, curveQuoteSellGross, defineLaunchpadChain, defineLaunchpadDeployment, defineLaunchpadDeploymentRegistry, defineLaunchpadTokenId, encodeLaunchpadPartnerHookData, feesFromGross, findLaunchpadLaunchConfig, findLaunchpadQuoteToken, getErc20Allowance, getErc20Balance, getLaunchpadApprovalStatus, getLaunchpadBuybackReleasable, getLaunchpadBuybackVest, getLaunchpadBuybackVestingDuration, getLaunchpadClaimableBalance, getLaunchpadCurrentSnipeTaxBps, getLaunchpadCurveAddress, getLaunchpadCurvePendingFees, getLaunchpadCurvePendingPartnerFee, getLaunchpadCurveProgress, getLaunchpadCurveState, getLaunchpadEmergencyDistributorAddress, getLaunchpadEmergencyExitState, getLaunchpadErc20Metadata, getLaunchpadFeePolicy, getLaunchpadGraduation, getLaunchpadGraduationFromCoordinator, getLaunchpadGraduationProgress, getLaunchpadHolderAdapterVersion, getLaunchpadHolderBinding, getLaunchpadHolderDistributor, getLaunchpadHolderDistributorState, getLaunchpadHolderEpoch, getLaunchpadLaunchConfig, getLaunchpadLaunchConfigCount, getLaunchpadLaunchConfigs, getLaunchpadLaunchGate, getLaunchpadLaunchRecord, getLaunchpadPartner, getLaunchpadPartnerClaimableBalance, getLaunchpadPartnerEpochAccounting, getLaunchpadPartnerEpochStatus, getLaunchpadPartnerPolicy, getLaunchpadPartnerUsability, getLaunchpadPendingCreatorRecipientChange, getLaunchpadPendingPartnerController, getLaunchpadPoolId, getLaunchpadPoolSweepState, getLaunchpadQuoteTokenEconomics, getLaunchpadSnipeTaxConfig, getLaunchpadTokenInfo, getLaunchpadTokenState, hasLaunchpadHolderClaimed, isLaunchpadHolderDistributor, isLaunchpadHolderExcluded, isLaunchpadHolderQuoteTokenAllowed, isLaunchpadSaltUsed, isLaunchpadTaxExempt, isLaunchpadToken, launchpadCreateParamsViolations, launchpadCreationSpender, launchpadCurveState, launchpadDeploymentRegistry, launchpadEconomicsHash, launchpadEconomicsHashFromDeployment, launchpadEmergencyExitAvailableAt, launchpadEmergencyRedeemQuoteOut, launchpadGraduateIsIdempotentSuccess, launchpadGraduationReady, launchpadHolderAllocationMatchesRoot, launchpadHolderInitializationData, launchpadHolderLeaf, launchpadHolderProofRoot, launchpadInitialBuyTokenOut, launchpadIsFinalRedemption, launchpadLaunchTaxExemptions, launchpadNetRequiredToBuy, launchpadPreparedContext, launchpadReservedTokens, launchpadSellableTokens, launchpadSpotPrice, launchpadTokensForNetQuote, mappedLaunchpadRevertNames, mulDivUp, parseLaunchpadReceiptEvents, predictLaunchpadAddresses, predictLaunchpadHolderDistributor, prepareApproveErc20, prepareCreateToken, prepareLaunchAndBuy, prepareLaunchWithHolderFeeSharing, prepareLaunchpadAcceptPartnerController, prepareLaunchpadBeginPoolFeeSweep, prepareLaunchpadBuy, prepareLaunchpadBuybackRelease, prepareLaunchpadCancelCreatorFeeRecipientOverride, prepareLaunchpadClaim, prepareLaunchpadCreateGraduatedPool, prepareLaunchpadCreatePartner, prepareLaunchpadEmergencyExit, prepareLaunchpadEmergencyRedeem, prepareLaunchpadExecuteCreatorFeeRecipientOverride, prepareLaunchpadFinalizePoolFeeSweep, prepareLaunchpadGraduate, prepareLaunchpadHolderClaim, prepareLaunchpadHolderClaimMany, prepareLaunchpadHolderHarvest, prepareLaunchpadHolderRollOver, prepareLaunchpadPartnerClaim, prepareLaunchpadProposeCreatorFeeRecipientOverride, prepareLaunchpadProposePartnerController, prepareLaunchpadReleaseOrphanedQuote, prepareLaunchpadRescueCurveFees, prepareLaunchpadRescueHookFees, prepareLaunchpadRescueHookPartnerFees, prepareLaunchpadRescuePartnerFees, prepareLaunchpadSell, prepareLaunchpadSetBuybackEnabled, prepareLaunchpadSetDeniedCreator, prepareLaunchpadSetLaunchEnabled, prepareLaunchpadSetPartnerEnabled, prepareLaunchpadSetPartnerName, prepareLaunchpadSetPartnerRecipient, prepareLaunchpadSetPartnerShare, prepareLaunchpadSetSnipeTax, prepareLaunchpadSetWhitelistedLauncher, prepareLaunchpadSettlePoolFeeSweepPartners, prepareLaunchpadSweepBucket, prepareLaunchpadSweepFees, prepareLaunchpadSyncDonatedTokens, prepareLaunchpadTransferCreatorFeeRecipient, quoteLaunchpadBuy, quoteLaunchpadBuyNet, quoteLaunchpadEmergencyRedeem, quoteLaunchpadNetRequiredToBuy, quoteLaunchpadSell, quoteLaunchpadSellGross, requireLaunchpadWriteAccount, resolveLaunchpadDeployment, resolvePinnedBlockNumber, revertErrorName, sendPreparedLaunchpadTransaction, simulateLaunchpadBuyExactIn, simulateLaunchpadSellExactIn, simulateLaunchpadWrite, snipeTaxCurrentBps, toDeadline, toLaunchpadCurveState, toLaunchpadError, toLaunchpadGraduationRecord, toLaunchpadGraduationStatus, toLaunchpadLaunchRecord, toLaunchpadTradeAvailability, toPreparedLaunchpadTransaction, validateAndResolveLaunchConfig, verifyLaunchpadDeployment, waitForLaunchpadTransaction, withAutoGraduationGasHeadroom };