Fiber LogoFiber Docs
Routing25 minute tutorial

Send a Multi-Hop Invoice Payment

Run sender and receiver Fiber nodes in one React page, copy the Invoice created by Node C, and paste it into Node A before paying through one public Fiber node.

InvoiceMulti-hopCopy and paste
1 Start two roles

Keep Node A and Node C as separate identities

The page starts two independent Fiber WASM nodes with different local keys and storage identifiers. Node A and Node C each connect to Bottle, but they open separate public channels and do not share private node state.

Node ABottle · Public nodeNode C
lib/fiber.ts · lines 11–24
2 Create the invoice

Let the receiver own the payment hash and preimage

After Node C has a ready public channel, call newInvoice(). Node C stores the invoice state and the secret required to settle the final TLC. The encoded Invoice is safe to hand to the payer.

lib/invoice.ts · lines 4–14
3 Transfer the invoice

Copy from Node C, then paste into Node A

Copying makes the boundary explicit: an Invoice is portable text, not a privileged server message. The same value could be delivered by QR code, chat, email, or another application without changing the Fiber payment.

No coordination backend

This tutorial keeps both nodes on one page for convenience, but transfers only the encoded Invoice through the clipboard. Production applications may choose any transport appropriate for their users.

lib/invoice-transfer.ts · lines 1–13
4 Observe invoice state

Poll the node that created the invoice

Node C calls getInvoice() and displays Open → Received → Paid. Cancelled and Expired are terminal outcomes too.

lib/invoice.ts · lines 16–22
5 Route the payment

Use Bottle as the single public intermediary

Node A submits the pasted Invoice with Bottle as its trampoline hop. Bottle receives through the A–Bottle channel and forwards through the separate Bottle–C channel. A fee cap prevents an unexpectedly expensive route.

lib/payment.ts · lines 5–14
6 Confirm both ends

Sender success and a paid Invoice complete the flow

Wait for Node A's payment to become terminal, then confirm that Node C reports Paid. The payment result also exposes the route that carried the transfer.

lib/payment.ts · lines 16–22
7 Wire React

Keep generated and pasted values separate

Node C owns generatedInvoice; Node A pays senderInvoice. Keeping two state values prevents the UI from silently transferring the Invoice behind the user's back.

app/multi-hop/page.tsx · lines 8–30