LayerHopDocsLaunch app (opens in a new tab)

Split the bill

One link for a group to pay a total in shares from any chain and token. Create splits with POST /v1/splits, tag payments with splitId and splitShare, and read who has paid with GET /v1/splits/{id}.

A split is a page, https://layerhop.com/split/<id>, that lists who owes what and who has paid. One person (the creator) is owed a total in one token on one chain. Everyone else opens the link, picks their share and pays it with whatever they hold, on any chain. Each payment is a normal LayerHop swap with the creator as the recipient: the payer sees every fee before signing, the usual web swap fee applies (a split adds none) and LayerHop never holds the funds.

Make one in the app at app.layerhop.com/split, or with the API below.

How do I create a split?#

Terminal
curl -X POST https://api.layerhop.com/v1/splits \
  -H "content-type: application/json" \
  -d '{"recipient":"alice.eth","chain":"base","token":"USDC","total":"120000000","participants":4,"note":"Dinner at Luigi'"'"'s"}'
  • recipient: an address, an ENS name or a .sol name, resolved like a pay link. The split stores the resolved address and shows it on the page.
  • chain and token: what the creator receives. Only listed tokens.
  • total: base units of token (an integer string; 120000000 is 120 USDC).
  • Shares, one of:
    • participants: 4: equal shares. They differ by at most one base unit; the first shares get the remainder (100 split 3 ways is 34, 33, 33).
    • shares: [{ "label": "Ana" }, { "label": "Bo" }]: equal shares with names.
    • shares: [{ "label": "Ana", "amount": "70000000" }, { "label": "Bo", "amount": "50000000" }]: custom amounts that add up to total exactly.
  • note: plain text, up to 140 characters.

2 to 50 people per split. The response is the split plus editToken and editUrl.

Who can edit a split?#

Whoever holds the edit secret. There is no sign-in: the secret (editToken) is returned once, when the split is created, and LayerHop stores only its SHA-256. The app keeps it in the browser that created the split and shows the edit link, https://layerhop.com/split/<id>#k=<secret>. The secret sits in the URL fragment, which browsers never send to a server, so it doesn't end up in logs. Anyone with the edit link can rename people, change the note and close the split, so keep it private. A lost secret can't be recovered; the split can still be paid and read.

Terminal
curl -X PATCH https://api.layerhop.com/v1/splits/spl_01k8x2m3n4p5q6r7s8t9v0w1x2 \
  -H "content-type: application/json" -H "x-edit-token: $EDIT_TOKEN" \
  -d '{"labels":["Ana","Bo","Cy","Di"],"status":"closed"}'

You can change labels (one per share), note (null clears it) and status (open or closed). Amounts can't change once people start paying. A closed split takes no more payments: quotes for it answer CONFLICT.

How does a payer pay a share?#

Quote a swap into the split's token on its chain, with the split's recipient, and tag it with the share:

Terminal
curl "https://api.layerhop.com/v1/quote?srcChain=arbitrum&srcToken=USDC&amount=30200000&dstChain=base&dstToken=USDC&sender=0xPAYER&recipient=0x1111111111111111111111111111111111111111&splitId=spl_01k8x2m3n4p5q6r7s8t9v0w1x2&splitShare=2&channel=web"

The API checks the split exists, is open, has that share, and that the quote delivers its token on its chain to its recipient (INVALID_PARAMS otherwise). Then build and send it like any other swap (POST /v1/orders, sign, POST /v1/orders/{quoteId}/submitted). The tag is recorded on the order; it never changes the fee or the route.

Quotes are for an input amount, so a payer sizes the payment to cover the share: the split page re-quotes with amount × share / dstAmountMin (plus 0.3%) until the quote's guaranteed minimum covers what's left of the share, and offers that amount.

When does a share count as paid?#

GET /v1/splits/{id} adds up, per share, what filled orders tagged with it delivered to the recipient: the amount read on chain after the fill, else the quote's guaranteed minimum. A share is paid once that is within 0.5% of its amount, partial below that. pending counts payments sent but not filled yet. The answer is never cached; the split page refreshes every 15 seconds.

JSON
{
  "id": "spl_01k8x2m3n4p5q6r7s8t9v0w1x2",
  "status": "open",
  "total": "120000000",
  "collected": "30000000",
  "paidCount": 1,
  "shares": [
    { "index": 0, "label": "Ana", "amount": "30000000", "received": "30000000", "status": "paid", "payments": 1, "pending": 0 },
    { "index": 1, "label": "Bo", "amount": "30000000", "received": "0", "status": "unpaid", "payments": 0, "pending": 1 }
  ]
}

Only payments made through LayerHop with the split's tag count. A payer who sends the token directly to the creator's address pays them just the same, but the split can't see it: the creator can close the split once everyone has paid.

Last updated