Skip to content
Open
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
18 changes: 18 additions & 0 deletions clawmes/lib/chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ class Chain:
block_explorer_url="https://blastscan.io",
is_l2=True,
),
4663: Chain(
chain_id=4663,
name="Robinhood Chain",
short_name="robinhood",
native_symbol="ETH",
native_decimals=18,
block_explorer_url="https://robinhoodchain.blockscout.com",
is_l2=True,
),
46630: Chain(
chain_id=46630,
name="Robinhood Chain Testnet",
short_name="robinhood-testnet",
native_symbol="ETH",
native_decimals=18,
block_explorer_url="https://robinhoodchain-testnet.blockscout.com",
is_l2=True,
),
}


Expand Down
33 changes: 20 additions & 13 deletions clawmes/services/clawnch.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,19 +290,25 @@ def prepare_deploy(
farcaster: str | None = None,
discord: str | None = None,
burn_tx_hash: str | None = None,
chain: str | None = None,
) -> dict[str, Any]:
"""Get unsigned Clanker factory calldata for a non-custodial deploy.
"""Get unsigned factory calldata for a non-custodial deploy.

Hits ``GET /api/prepare/deploy``. Returns the envelope shape:
``chain`` (``"base"`` or ``"robinhood"``) is forwarded as the
``chain`` query param to ``GET /api/prepare/deploy``. The server
resolves it into Clanker-vs-Bags calldata. Default is Base.

Returns the envelope shape:

{
"ok": True,
"data": {"to": "0xE85A…", "data": "0xdf40224a…", "value": "0x0", "chainId": 8453},
"data": {"to": "0x…", "data": "0x…", "value": "0x…", "chainId": 8453},
"meta": {
"platformFeeBps": 2000,
"userFeeBps": 8000,
"vaultPercentage": 0,
"source": "base-mcp",
"vaultPercentage": 0, # 0 on the Robinhood path
"creationFeeWei": "0", # non-zero on Robinhood
"chain": "base" | "robinhood",
...
},
}
Expand All @@ -315,16 +321,15 @@ def prepare_deploy(
- No API key required (``/api/prepare/deploy`` is public).
- No captcha solving — the wallet signs the deploy tx directly.
- The user's wallet pays gas.
- Same 20% platform fee preserved in the rewards array.
- Same 20% platform fee preserved in the rewards array (Base)
or the Bags claimer array (Robinhood).

``burn_tx_hash`` is **mandatory upstream**: every launch
``burn_tx_hash`` is **mandatory upstream on Base**. Every launch
requires a verified 1,000,000+ $CLAWNCH burn from
``from_address`` to the dead address within 24h. Calling
without one raises ``ClawnchError`` with
``code="burn_required"`` (HTTP 402) whose ``meta`` carries
``minBurnTokens`` + ``burnAddress``. A verified burn also sets
the vault clause baked into the returned calldata (1M = 1%,
up to 10M = 10%).
``from_address`` to the dead address within 24h; the Robinhood
path doesn't enforce it (Bags doesn't burn). Calling without one
raises ``ClawnchError`` with ``code="burn_required"`` whose
``meta`` carries ``minBurnTokens`` + ``burnAddress``.
"""
if not from_address:
raise ClawnchError("bad_request", "from_address is required")
Expand Down Expand Up @@ -354,6 +359,8 @@ def prepare_deploy(
params["discord"] = discord
if burn_tx_hash:
params["burnTxHash"] = burn_tx_hash
if chain:
params["chain"] = chain.lower()

# Public endpoint — no auth header sent.
body = self._get("/api/prepare/deploy", params=params)
Expand Down
5 changes: 5 additions & 0 deletions clawmes/services/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
10: "https://mainnet.optimism.io",
# Polygon — official public RPC
137: "https://polygon-rpc.com",
# Robinhood Chain — official public RPC. Rate-limited; Alchemy /
# QuickNode / Chainstack / dRPC offer dedicated endpoints on 4663.
4663: "https://rpc.mainnet.chain.robinhood.com",
# Robinhood Chain Testnet — official public RPC.
46630: "https://rpc.testnet.chain.robinhood.com",
}


Expand Down
13 changes: 8 additions & 5 deletions clawmes/tools/clawnch_fees.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
far). Uses Clawnch's ``/api/launches?address=…`` endpoint.

Claim-side ops aren't implemented here today: Clanker pays creator
rewards via its own LP-fee accumulator (FeeLocker), not via a
launchpad-controlled "claim()" function. Users claim through their
Clanker dashboard or directly against the FeeLocker contract. Once
v2 ships (the ClawnchFactory fork that drops Clanker), we'll revisit
adding a launchpad-orchestrated claim action.
rewards via its own LP-fee accumulator (FeeLocker) on Base, and Bags
pays creator rewards via its own per-token ``BagsFeeShare`` ledger on
Robinhood Chain (the per-token ``claim()`` on the feeShare contract
returned by a Bags launch). Neither flows through Clawnch's HTTP claim
path — Clawnch only reads launch metadata. Users claim through their
Clanker dashboard (Base) or against the token's feeShare contract
(Robinhood). Once v2 ships (the ClawnchFactory fork that drops
Clanker), we'll revisit adding a launchpad-orchestrated claim action.

Requires ``CLAWNCH_API_KEY`` for ``my_launches``; ``launch_info`` is
public and works without a key.
Expand Down
69 changes: 49 additions & 20 deletions clawmes/tools/clawnch_launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,17 @@ def _normalize_social(value: str, base_url: str) -> str:
name="clawnch_launch",
toolset="clawmes-defi",
description=(
"Deploy a token on Base via the Clawnch launchpad. Clawnch "
"handles the deploy + initial liquidity atomically via the "
"Clanker SDK; the user's wallet signs a captcha challenge to "
"prove identity. Every deploy requires burn_tx_hash — a "
"verified 1,000,000+ $CLAWNCH burn (use /burn to submit one). "
"Supports image + social metadata (twitter / website / "
"telegram / farcaster / discord). Requires CLAWNCH_API_KEY "
"(register an agent with /register_agent)."
"Deploy a token via the Clawnch launchpad. Defaults to Base "
"(via Clanker); use --chain robinhood to launch on Robinhood "
"Chain via Bags.fm. Clawnch handles the deploy + initial "
"liquidity atomically; the user's wallet signs a captcha "
"challenge to prove identity (custodial) or signs the deploy tx "
"directly (non-custodial). Every deploy on Base requires a "
"verified 1,000,000+ $CLAWNCH burn (use /burn to submit one); "
"the Robinhood path currently doesn't enforce a burn. Supports "
"image + social metadata (twitter / website / telegram / "
"farcaster / discord). Requires CLAWNCH_API_KEY (register an "
"agent with /register_agent)."
),
schema=_SCHEMA,
emoji="\U0001f31f",
Expand Down Expand Up @@ -202,12 +205,32 @@ def _handle_deploy(args: dict[str, Any]) -> str:
bypass = read_str(args, "bypass_tx_hash") or None
burn = read_str(args, "burn_tx_hash") or None

# Classic non-custodial prepare path. The API routes chain based on a
# `chain` query param, which we pass through if the caller supplied it.
start_deploy_chain = read_str(args, "chain") or None

try:
result = get_clawnch_service().deploy(
token_params=token_params,
bypass_tx_hash=bypass,
burn_tx_hash=burn,
)
if start_deploy_chain == "robinhood":
result = get_clawnch_service().prepare_deploy(
from_address=args.get("from_address") or "",
name=name,
symbol=symbol,
description=token_params.get("description"),
image=token_params.get("image"),
twitter=token_params.get("twitter"),
website=token_params.get("website"),
telegram=token_params.get("telegram"),
farcaster=token_params.get("farcaster"),
discord=token_params.get("discord"),
burn_tx_hash=burn,
chain="robinhood",
)
else:
result = get_clawnch_service().deploy(
token_params=token_params,
bypass_tx_hash=bypass,
burn_tx_hash=burn,
)
except ClawnchError as exc:
if exc.code == "burn_required":
meta = exc.meta or {}
Expand All @@ -225,15 +248,21 @@ def _handle_deploy(args: dict[str, Any]) -> str:

tx_hash = result.get("txHash") or result.get("tx_hash")
token_address = result.get("tokenAddress") or result.get("token_address")
# Desktop UI: Clawnch launches are Base-only, so surface the tx explorer
# link plus Clanker / DexScreener / token-explorer links for the brand-new
# token as clickable Link artifacts. The enrich helpers no-op on missing or
# malformed values, so we call them unconditionally (passive descriptive
# keys — no preview auto-open from the tool itself).

# Surface the actual chain from the launch response. The clawn.ch API
# returns chainId in `data.chainId` (prepare path) or the deploy
# metadata; default to Base when absent so historical Base launches
# stay Base-tagged.
chain_id = int(result.get("chainId") or result.get("chain_id") or 8453)

# Desktop UI: surface the tx explorer link + token links for the
# brand-new token as clickable Link artifacts. Passive descriptive
# keys right now — no preview auto-open. enrich helpers no-op on
# missing values.
from clawmes.lib.ui_artifacts import enrich_token_links, enrich_tx_links

enrich_tx_links(result, tx_hash=tx_hash or "", chain_id=8453)
enrich_token_links(result, token=token_address or "", chain_id=8453)
enrich_tx_links(result, tx_hash=tx_hash or "", chain_id=chain_id)
enrich_token_links(result, token=token_address or "", chain_id=chain_id)

# Desktop UI: render a launch-receipt card and surface its path at the
# envelope top level (json_result ``preview=``) so the desktop opens it in
Expand Down
Loading