Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Creators choose a 0 / 1 / 3 % trading fee that is pushed **in full** to benefici
- **Any quote asset.** ETH, USDG, USDC on Arc, **TWIG** ([Twigpine](https://twigpine.com)'s token on Base: a 1:1 wrapper of GITLAWB,
wrap or unwrap any time with no fee; priced at GITLAWB's price; fees paid or burned in TWIG; no longer offered in the Base form, ahead of the planned
[token migration](https://migrate.twigpine.com), while launches already paired with it keep their badge, price and trading), **GITLAWB** ([Twigpine](https://twigpine.com)'s token, on Base and bridged 1:1 to
Robinhood Chain; priced from its Base Uniswap v4 WETH pool; fees paid or burned in GITLAWB; the Robinhood Chain form offers it), or a **tokenized stock**: Coinbase's B20 stocks on Base
Robinhood Chain; priced from its Base Uniswap v4 WETH pool; fees paid or burned in GITLAWB; no longer offered in any launch form, for the same migration, while launches already paired with it keep their badge, price and trading), or a **tokenized stock**: Coinbase's B20 stocks on Base
(every stock Coinbase lists: NVDAc, AAPLc, TSLAc, NFLXc, …, and new listings picked up from Coinbase's registry as they appear; shown in USD where Chainlink publishes an on-chain feed) and Robinhood Stock Tokens on Robinhood Chain.
- **Trade in-page.** Buys and sells go straight to the Uniswap v4 pool through the Universal Router; the site
never touches funds.
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/agents/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
<div className={styles.reference}>
<div className={styles.referenceHeading}><Braces size={16} aria-hidden="true" /><h3>Parameters, without the guesswork</h3></div>
<dl className={styles.parameters}>
<div><dt><code>quote</code></dt><dd>ETH uses address zero. For GITLAWB on Robinhood Chain use <code>0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D</code>; for USDG on Robinhood Chain, <code>0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168</code>. On Base, TWIG (<code>0x6aC18bcf4eDE02591d4917452700ea5eaAea13c1</code>) and GITLAWB (<code>0x5F980Dcfc4c0fa3911554cf5ab288ed0eb13DBa3</code>) are still recognised, badged and priced, but the Base form offers neither: GITLAWB left it when TWIG took its place, and TWIG left it ahead of the planned token migration. For any ERC-20 quote call <code>findSalt(...)</code> first so the token address sorts above the quote.</dd></div>
<div><dt><code>quote</code></dt><dd>ETH uses address zero. For USDG on Robinhood Chain use <code>0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168</code>. TWIG (<code>0x6aC18bcf4eDE02591d4917452700ea5eaAea13c1</code>, Base) and GITLAWB (<code>0x5F980Dcfc4c0fa3911554cf5ab288ed0eb13DBa3</code> on Base, <code>0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D</code> on Robinhood Chain) are still recognised, badged and priced. No form offers them now. GITLAWB left the Base form when TWIG took its place; then TWIG left the Base form and GITLAWB the Robinhood Chain form, ahead of the planned token migration. For any ERC-20 quote call <code>findSalt(...)</code> first so the token address sorts above the quote.</dd></div>

Check notice on line 79 in app/src/app/agents/page.tsx

View workflow job for this annotation

GitHub Actions / pr-guard

pr-guard: On-chain address

app/src/app/agents/page.tsx: 0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D (already in the repository)

Check notice on line 79 in app/src/app/agents/page.tsx

View workflow job for this annotation

GitHub Actions / pr-guard

pr-guard: On-chain address

app/src/app/agents/page.tsx: 0x5F980Dcfc4c0fa3911554cf5ab288ed0eb13DBa3 (already in the repository)

Check notice on line 79 in app/src/app/agents/page.tsx

View workflow job for this annotation

GitHub Actions / pr-guard

pr-guard: On-chain address

app/src/app/agents/page.tsx: 0x6aC18bcf4eDE02591d4917452700ea5eaAea13c1 (already in the repository)

Check notice on line 79 in app/src/app/agents/page.tsx

View workflow job for this annotation

GitHub Actions / pr-guard

pr-guard: On-chain address

app/src/app/agents/page.tsx: 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 (already in the repository)
<div><dt><code>supply</code></dt><dd><code>0</code> means the default <code>1B</code> supply.</dd></div>
<div><dt><code>startTick</code></dt><dd>Sets the opening market cap. A multiple of <code>200</code>; <code>184200 ≈ 10 ETH</code> FDV for <code>1B</code> supply.</dd></div>
<div><dt><code>lpFee</code></dt><dd>In pips: <code>0</code>, <code>10000 = 1%</code>, or <code>30000 = 3%</code>.</dd></div>
Expand Down
16 changes: 10 additions & 6 deletions app/src/app/api/quotes/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NextResponse } from "next/server";
import { isChainKey } from "@/lib/chainPublic";
import { launchpad } from "@/lib/launchpad/config";
import { launchpad, officialQuotes, type Quote } from "@/lib/launchpad/config";
import { STOCK_SOURCE, baseStockList, ensureRegistry, refreshBaseRegistry, stockIssued, stockList, stockPrices } from "@/lib/launchpad/stocksServer";
import { searchStocks } from "@/lib/launchpad/stocks";
import { BASE_STOCK_SEARCH_LIMIT, searchBaseStocks, stockTileSvg } from "@/lib/launchpad/baseStocks";
Expand All @@ -13,8 +13,11 @@ export const dynamic = "force-dynamic";
type StockHit = { key: "stock"; address: string; symbol: string; name: string; decimals: number; usd: number | null; logo: string | null; issued: boolean | null };

/**
* GET /api/quotes?chain=<base|robinhood|arc>[&q=AAPL] → quote assets the launch form may offer on that chain:
* the fixed ones (ETH, USDG, USDC, GITLAWB on Robinhood Chain with GITLAWB's live USD; never TWIG, which left the Base form) plus tokenized stocks from that chain's registry (with live USD where the stock has a price):
* GET /api/quotes?chain=<base|robinhood|arc>[&q=AAPL] → the chain's quote assets with live USD:
* `fixed` = the form's own quotes (ETH, USDG, USDC: `offered: true`) then the official ones the form no longer offers
* (TWIG and GITLAWB on Base, GITLAWB on Robinhood Chain: `offered: false`, priced at GITLAWB's live price). Outside
* callers read prices from it by key (Playground prices its tokenize launches here), so the official ones stay listed;
* the launch form itself reads only `stocks`. Plus tokenized stocks from that chain's registry (with live USD where the stock has a price):
* Coinbase tokenized stocks on Base, Robinhood Stock Tokens on Robinhood Chain, none on Arc.
* `stocks` is one page of matches; `stocksMatched` is how many match the search in all and `stocksTotal` how many the chain's registry holds, so the form can say there are more.
* Each stock's `issued` says whether any of it is in circulation: false = none yet (nobody can buy with it), null = not known (Robinhood, or no good read yet).
Expand All @@ -26,10 +29,11 @@ export async function GET(req: Request) {
if (!isChainKey(chain)) return NextResponse.json({ error: "bad chain" }, { status: 400 });
const q = (u.searchParams.get("q") ?? "").slice(0, 12);
const gl = await gitlawbUsd(); // one price for both chains: the Robinhood token is the Base token bridged 1:1
const fixed = launchpad(chain).quotes.map((x) => {
const priced = (x: Quote, offered: boolean) => {
const linked = gitlawbLinkedUsd(x.key, gl); // GITLAWB, and TWIG (unwraps 1:1 to GITLAWB), take GITLAWB's live price
return { ...x, usd: linked === undefined ? x.usd : linked };
});
return { ...x, usd: linked === undefined ? x.usd : linked, offered };
};
const fixed = [...launchpad(chain).quotes.map((x) => priced(x, true)), ...officialQuotes(chain).map((x) => priced(x, false))];
const { stocks, stocksTotal, stocksMatched } = await memo(`quotes:stocks:${chain}:${q.toUpperCase()}`, 30_000, async (): Promise<{ stocks: StockHit[]; stocksTotal: number; stocksMatched: number }> => {
let hits: { address: string; symbol: string; name: string; decimals: number; logo: string | null }[];
let matched: number;
Expand Down
5 changes: 2 additions & 3 deletions app/src/app/launch/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Metadata } from "next";
import { pageMetadata } from "@/lib/seo";
import LaunchForm from "@/components/launchpad/LaunchForm";
import { ethUsd } from "@/lib/launchpad/ethPrice";
import { gitlawbUsd } from "@/lib/launchpad/gitlawbServer";
import { DEFAULT_CHAIN, chainKeyOr, type ChainKey } from "@/lib/chainPublic";
import { CONFIGURED_CHAINS, launchpad } from "@/lib/launchpad/config";

Expand All @@ -22,15 +21,15 @@ function initialChainFor(param: string | undefined): ChainKey {

export default async function LaunchPage({ searchParams }: { searchParams: Promise<{ chain?: string }> }) {
const sp = await searchParams;
const [usd, gitlawb] = await Promise.all([ethUsd(), gitlawbUsd()]);
const usd = await ethUsd();
return (
<>
<main className="relative mx-auto max-w-6xl px-4 pt-6 sm:pt-10 pb-16 space-y-5 sm:space-y-6">
<header className="max-w-2xl">
<h1 className="font-display font-bold tracking-[-0.02em] text-ink text-3xl sm:text-4xl">Launch a token</h1>
<p className="mt-2 text-base text-body">Pick a chain, fill this in, sign once, done. No platform fee. You only pay gas.</p>
</header>
<LaunchForm ethUsd={usd} gitlawbUsd={gitlawb} initialChain={initialChainFor(sp.chain)} />
<LaunchForm ethUsd={usd} initialChain={initialChainFor(sp.chain)} />
</main>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions app/src/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

## What a launch does
1. deploys a fixed-supply ERC-20 (1,000,000,000; no mint/pause/blacklist/tax/owner)
2. initializes a Uniswap v4 pool quote/token (quote = ETH, GITLAWB or USDG on Robinhood Chain, USDC on Arc, or a registry stock token, all in the form; also TWIG, GITLAWB, USDC or WETH on Base, priced but not in the form; tick spacing 200, no hook) at the chosen start tick
2. initializes a Uniswap v4 pool quote/token (quote = ETH, USDG on Robinhood Chain, USDC on Arc, or a registry stock token, all in the form; also TWIG, GITLAWB, USDC or WETH on Base and GITLAWB on Robinhood Chain, priced but not in the form; tick spacing 200, no hook) at the chosen start tick
3. mints one single-sided position holding 100% of supply to an ownerless locker (no withdraw path exists)
4. registers fee routing: lpFee 0 | 10000 (1%) | 30000 (3%) pips; recipients [] = fees burned,
else {payout,bps}[] summing to 10000. Fixed forever.
Expand All @@ -87,7 +87,7 @@
WETH (Base, 18 dec): 0x4200000000000000000000000000000000000006 (priced at ETH; buyers pay WETH, not ETH)
TWIG (Base, 18 dec): 0x6aC18bcf4eDE02591d4917452700ea5eaAea13c1 (Twigpine's token: 1:1 wrapper of GITLAWB, wrap/unwrap any time, no fee; no longer offered in the Base form, launches already paired with it keep trading; priced = GITLAWB; fees paid in TWIG, burned when recipients = [])
GITLAWB (Base, 18 dec): 0x5F980Dcfc4c0fa3911554cf5ab288ed0eb13DBa3 (Twigpine's token; still recognised and priced on Base; fees paid in GITLAWB, burned when recipients = [])
GITLAWB (Robinhood, 18 dec): 0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D (LayerZero OFT of the Base token, 1:1)
GITLAWB (Robinhood, 18 dec): 0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D (LayerZero OFT of the Base token, 1:1; no longer offered in the Robinhood Chain form, launches already paired with it keep trading)

Check notice on line 90 in app/src/app/llms.txt/route.ts

View workflow job for this annotation

GitHub Actions / pr-guard

pr-guard: On-chain address

app/src/app/llms.txt/route.ts: 0xd1b0d44E4f6ed940fcC7A9F59Bf30Daf62cCFe3D (already in the repository)

## Launch (contract call)
factory.launch((name, symbol, metadataURI, quote, supply=0, startTick, lpFee, salt, recipients))
Expand Down
4 changes: 2 additions & 2 deletions app/src/app/rules/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const metadata: Metadata = pageMetadata({ path: "/rules", title: "How it

const STEPS = [
{ title: "Your token is deployed", description: "A plain ERC-20 with EIP-2612 permit. Fixed supply, 1 billion by default. No mint, no pause, no blacklist, no transfer tax, no owner.", value: "1B", label: "default supply" },
{ title: "A market opens", description: "A Uniswap v4 pool pairs your token with ETH, GITLAWB or USDG on Robinhood Chain, a tokenized stock (Coinbase stocks on Base, Robinhood Stock Tokens on Robinhood Chain), or USDC on Arc. No hook. The pool starts at the market cap you pick.", value: "v4", label: "Uniswap pool" },
{ title: "A market opens", description: "A Uniswap v4 pool pairs your token with ETH, USDG on Robinhood Chain, a tokenized stock (Coinbase stocks on Base, Robinhood Stock Tokens on Robinhood Chain), or USDC on Arc. No hook. The pool starts at the market cap you pick.", value: "v4", label: "Uniswap pool" },
{ title: "The liquidity position is locked", description: "100% of the supply goes into one single-sided position at launch. Its NFT is minted to an ownerless locker that has no function to withdraw, transfer or shrink it. Ever.", value: "100%", label: "deposited at launch" },
{ title: "Fee routing is written in", description: "The trading fee you choose (0%, 1% or 3%) goes 100% to the beneficiaries you name, or is burned if you name none. Fixed at launch, unchangeable.", value: "0 / 1 / 3%", label: "your trading fee" },
] as const;
Expand Down Expand Up @@ -137,7 +137,7 @@ export default function RulesPage() {
<details open><summary>Why is my token under &ldquo;quiet launches&rdquo;?<ChevronDown size={17} aria-hidden="true" /></summary><div><p>The home page ranks by facts, not by launch order. A token is <strong>live</strong> once a wallet other than its launcher has traded it in the last 24 hours; trades in the launch block and the next three blocks (snipe bots) don&apos;t count, and neither do the launcher&apos;s own. Live tokens rank by outside wallets in the last hour, then today, then by their last outside trade. A wallet&apos;s newest launch gets its first hour on the board regardless; after that it sits under quiet launches, one row per wallet, until someone trades it.</p><p>Nothing is hidden: every launch stays in the New tab, in search and in the API. The only way up is a trade from an outside wallet.</p></div></details>
{boostEnabled() ? <BoostRulesEntry /> : null}
<details open><summary>What can change after launch?<ChevronDown size={17} aria-hidden="true" /></summary><div><p>Nothing on-chain can be edited after launch: not the name, not the fee, not the beneficiaries. Metadata (image, description, links) is stored by this site and can change; the token itself cannot.</p></div></details>
<details open><summary>What is a TWIG- or GITLAWB-quoted pool?<ChevronDown size={17} aria-hidden="true" /></summary><div><p>TWIG is Twigpine&apos;s token on Base: a 1:1 wrapper of GITLAWB. Anyone can wrap GITLAWB into TWIG, or unwrap it back, at any time with no fee, and every TWIG is backed by one GITLAWB held in its contract, which has no owner and no transfer restrictions. The Base form no longer offers it, ahead of the planned GITLAWB and TWIG token migration (<a href={TWIG_MIGRATE_URL} target="_blank" rel="noreferrer" className="underline decoration-line underline-offset-2 hover:text-ink">migrate.twigpine.com</a>). Launches already paired with TWIG keep their badge, price and trading: buyers pay in TWIG; any trading fee is paid in TWIG to the beneficiaries named at launch (by their shares) when it is collected, and a launch that names none has its TWIG fees burned when they are collected.</p><p>GITLAWB is Twigpine&apos;s token on Base, bridged 1:1 to Robinhood Chain over LayerZero (one supply, two chains): an ordinary ERC-20 with no transfer restrictions and no issuer switch. The Robinhood Chain form offers it; on Base, pools already paired with GITLAWB keep their badge and price. Fees work the same way: paid in GITLAWB when collected, and a launch that names no beneficiary has its GITLAWB fees burned when they are collected.</p><p>Dollar figures for both come from the Uniswap v4 WETH/GITLAWB pool price on Base, cross-checked against a 30-minute on-chain average, and ETH/USD; one TWIG counts as one GITLAWB, since it unwraps to one. They are for display and sorting only; nothing on-chain depends on them.</p></div></details>
<details open><summary>What is a TWIG- or GITLAWB-quoted pool?<ChevronDown size={17} aria-hidden="true" /></summary><div><p>TWIG is Twigpine&apos;s token on Base: a 1:1 wrapper of GITLAWB. Anyone can wrap GITLAWB into TWIG, or unwrap it back, at any time with no fee, and every TWIG is backed by one GITLAWB held in its contract, which has no owner and no transfer restrictions. The Base form no longer offers it, ahead of the planned GITLAWB and TWIG token migration (<a href={TWIG_MIGRATE_URL} target="_blank" rel="noreferrer" className="underline decoration-line underline-offset-2 hover:text-ink">migrate.twigpine.com</a>). Launches already paired with TWIG keep their badge, price and trading: buyers pay in TWIG; any trading fee is paid in TWIG to the beneficiaries named at launch (by their shares) when it is collected, and a launch that names none has its TWIG fees burned when they are collected.</p><p>GITLAWB is Twigpine&apos;s token on Base, bridged 1:1 to Robinhood Chain over LayerZero (one supply, two chains): an ordinary ERC-20 with no transfer restrictions and no issuer switch. No launch form offers it any more, ahead of the same planned migration; pools already paired with GITLAWB, on either chain, keep their badge, price and trading. Fees work the same way: paid in GITLAWB when collected, and a launch that names no beneficiary has its GITLAWB fees burned when they are collected.</p><p>Dollar figures for both come from the Uniswap v4 WETH/GITLAWB pool price on Base, cross-checked against a 30-minute on-chain average, and ETH/USD; one TWIG counts as one GITLAWB, since it unwraps to one. They are for display and sorting only; nothing on-chain depends on them.</p></div></details>
<details open><summary>What should I know about stock-quoted pools?<ChevronDown size={17} aria-hidden="true" /></summary><div><p>Stock-quoted pools use tokenized stocks as the quote asset: Coinbase tokenized stocks (B20) on Base, recognised here only from Coinbase&apos;s official list and priced in dollars where Chainlink publishes an on-chain feed (the others show no dollar price); Robinhood Stock Tokens on Robinhood Chain, recognised only from Robinhood&apos;s own registry.</p><p>Both are securities issued by third parties under Regulation S and are not offered to US persons. Coinbase&apos;s also exclude the UK, Canada, Australia, Singapore and Switzerland. Their issuers can pause transfers or freeze wallets in restricted jurisdictions. Holding or trading them is subject to the issuer&apos;s terms, not ours.</p></div></details>
</div>
</section>
Expand Down
3 changes: 2 additions & 1 deletion app/src/components/launchpad/GitlawbBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export function GitlawbMark({ size = 16, className = "" }: { size?: number; clas

/**
* Badge for tokens paired with GITLAWB. Shown wherever a token appears (list, trending, feed, token page,
* dashboard, share card) — the visible perk of picking GITLAWB as the quote asset. "sm" is 20px tall so it sits
* dashboard, share card). No launch form offers GITLAWB any more (the token migration); launches already paired with it
* keep the badge. "sm" is 20px tall so it sits
* inside a text-sm line without changing row heights. Black like the logo tile,
* white text, a light hairline in dark mode so it still reads as a chip on a dark page. `collapse` shows the mark
* alone on phones, keeping the label for screen readers.
Expand Down
Loading
Loading