> For the complete documentation index, see [llms.txt](https://docs.antivamp.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.antivamp.io/for-launchpads/payer-split.md).

# Payer Split & Launcher Delegation

Let a funded wallet pay for a reservation while an embedded (Privy) wallet stays the authorized launcher — and rescue holds that are already stranded.

> **Built for embedded-wallet launchpads.** On Privy-style platforms the wallet that launches is an in-app embedded wallet — usually unfunded — while the user's SOL lives in a browser extension. The payer split lets each wallet do its job.

## Why this exists

The on-chain programs bind the reservation to the wallet that pays (the Solana program records the fee payer as the holder; EVM registries record `msg.sender`). Without a split, a hold paid by an extension wallet is authorized to that extension wallet — and a launch from the embedded wallet is correctly refused, stranding the fee.

Enforcement is AntiVamp's signed validate decision, so the split is implemented there: the payer owns the hold on-chain, and a **verified launcher delegation** authorizes the embedded wallet to launch. A delegation only ever **adds one wallet** — it never removes the holder's rights, never shortens protection, and never overrides a guardian block.

## New reservations: `payer` on prepare (Solana)

Pass `payer` alongside `launcher` on [`POST /v1/reservations/prepare`](/developers/api-reference.md). When present:

* the transaction is built with `payer` as fee payer and funding source,
* `launcher` stays the authorized launcher of the resulting hold (via delegation written at on-chain confirmation),
* `payer` defaults to `launcher` when omitted — nothing changes for existing integrators.

Because the program cannot demand a second signer, the launcher co-signs **off-chain**: include `launcherApproval`, the launcher's ed25519 signature over the canonical message. Privy signs messages silently, so this costs the user nothing — and it closes the griefing vector (nobody can create holds naming an arbitrary launcher without that wallet's consent).

```
antivamp:payer-split:v1:<environment>:<launchpad>:<chain>:<identityKey>:<launcher>:<payer>:<durationSeconds>
```

```bash
curl -X POST https://antivamp.io/api/v1/reservations/prepare \
  -H 'Authorization: Bearer av_live_…' -H 'Content-Type: application/json' \
  -d '{
    "chain": "solana",
    "name": "Green Robin",
    "ticker": "ROBIN",
    "durationSeconds": 86400,
    "launcher": "<privy embedded wallet>",
    "payer": "<funded extension wallet>",
    "launcherApproval": "<launcher ed25519 signature over the canonical message>"
  }'
```

Send `payer` without `launcherApproval` and the API returns `400 launcher_approval_required` with `details.expectedMessage` — the exact string to sign.

{% hint style="info" %}
🎯 **Griefing is closed by construction.** The on-chain hold (and the per-wallet active cap) binds the **payer**, and a launcher can only be named with its own signature. Nobody can fill a victim's reservation slots or name them on a hold they didn't approve.
{% endhint %}

EVM chains reject `payer` (`400 payer_unsupported_chain`): the registries bind the sending wallet, so the payer must submit the transaction itself. Use the delegation endpoint below after reserving if the launcher differs.

## Existing holds: `delegate-launcher` (all chains)

Holds that are already stranded — paid by a wallet that cannot launch — are rescued with [`POST /v1/reservations/delegate-launcher`](/developers/api-reference.md):

```bash
# 1) Call without a signature to get the exact message to sign:
curl -X POST https://antivamp.io/api/v1/reservations/delegate-launcher \
  -H 'Authorization: Bearer av_live_…' -H 'Content-Type: application/json' \
  -d '{"chain":"solana","name":"PUMP","ticker":"PUMP","delegate":"<embedded wallet>"}'
# → 400 signature_required, details.expectedMessage + details.holder

# 2) Sign details.expectedMessage with the CURRENT holder wallet, then retry:
curl -X POST https://antivamp.io/api/v1/reservations/delegate-launcher \
  -H 'Authorization: Bearer av_live_…' -H 'Content-Type: application/json' \
  -d '{"chain":"solana","name":"PUMP","ticker":"PUMP",
       "delegate":"<embedded wallet>","signature":"<holder signature>"}'
```

Rules:

* The holder is resolved from **chain state**, never from the request, and the hold must be active.
* Only the current holder's signature (Solana ed25519 / EVM EIP-191) creates a delegation.
* One delegation per identity; a new one replaces the previous.
* `validate` and `identity/check` responses for a delegated identity carry `delegatedLauncher`, and the public identity page ([antivamp.io/identity/…](https://antivamp.io/explorer)) lists both wallets — the holder and the delegate.

### From the SDK

Both halves work through `@antivamp_io/sdk` (0.2.4+): `prepareReservation` accepts `payer` and `launcherApproval`, and `delegateLauncher` wraps the rescue flow:

```ts
import { AntiVampClient, AntiVampApiError } from "@antivamp_io/sdk";
const av = new AntiVampClient({ apiKey: process.env.ANTIVAMP_API_KEY! });

// 1) Get the exact message the holder must sign:
let expectedMessage: string, holder: string;
try {
  await av.delegateLauncher({ chain: "solana", name: "PUMP", ticker: "PUMP", delegate: embeddedWallet });
} catch (err) {
  if (err instanceof AntiVampApiError && err.code === "signature_required") {
    ({ expectedMessage, holder } = err.details as { expectedMessage: string; holder: string });
  } else throw err;
}

// 2) Sign expectedMessage with the holder wallet, then:
await av.delegateLauncher({
  chain: "solana", name: "PUMP", ticker: "PUMP",
  delegate: embeddedWallet, signature: holderSignature,
});
```

### Self-serve on antivamp.io (no API key)

Creators can delegate without any integration: on [antivamp.io/reservations](https://antivamp.io/reservations), connect the wallet that holds the reservation — each active hold shows a **"Delegate launch rights"** action. Enter the delegate address, sign the message in-wallet, done. The endpoint itself also accepts keyless calls (the holder's signature is the security boundary; anonymous calls are IP rate limited and always operate on production data).

## What validate returns

A launch from the delegate resolves exactly like one from the holder: `status: "authorized"`, `decision: "allow"`, `launcherAuthorized: true` — plus `delegatedLauncher` set to the delegate's address. Launches from any third wallet are still blocked.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.antivamp.io/for-launchpads/payer-split.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
