Fiber LogoFiber Docs
Interactive tutorial · About 15 minutes

Open a Fiber Channel and Send a Payment

Fund your browser node, open a real Fiber Testnet channel, and send 1 CKB to a public peer. Testnet confirmations may take longer than the active tutorial time.

Need background on browser nodes? Review Connect to Fiber with a WASM Node.

1

Prepare node. Start and connect.

2

Fund address. Receive Testnet CKB.

3

Open channel. Commit the peer minimum on-chain.

4

Send payment. Send CKB to the peer.

NodeReady to start
PeerNode required
ChannelNot opened
PaymentNot sent
1
Prepare browser nodeStart locally and connect over WSS. This does not move funds.
2
Fund the address
Balance: · auto-checks every 5s
3
Open a 499 CKB channel
4
Send CKB to the peer
Runtime events and results
stateReady to start
connectionOffline
Channel and payment events will appear here.
Implementation walkthrough

Behind the scenes

Follow the data and SDK calls that prepare the node, fund and open the channel, then confirm the payment.

Architecture

Understand the channel payment flow

openChannel() locks a chosen amount of Testnet CKB on-chain. Once the channel is ready, pay() can make multiple off-chain payments without creating a new CKB transaction for every small amount.

Your browser nodeFiber WASM
→ Fiber channel →
Public Fiber peerReceives payment
Testnet state is real

Preparing the node starts it locally and connects it to the public peer. Opening the channel and sending payments are separate actions.

app/pay/page.tsx · lines 39–48
1 Prepare the node

Start the node and derive its funding address

start() starts the browser node and reveals the Testnet address that must be funded. It calls startFiber(), reads the node information, and uses scriptToAddress() to convert default_funding_lock_script into its Testnet address.

The demo combines startup and connectToRouter() into one preparation action. The downloaded source keeps the helpers separate, so an application can expose more control when needed.

app/pay/page.tsx · lines 23–31
2 Watch funding

Detect sufficient Testnet funding

queryCkbBalance() calls CKB RPC get_cells_capacity to measure the address's available capacity. watchCkbBalance() repeats the check every five seconds while the page is visible, allowing the interface to unlock channel creation once the address can cover the funding amount.

Use Testnet funds only

The public peer accepts CKB channels at or above 499 CKB. Keep extra Testnet CKB available for the transaction fee.

lib/balance.ts · lines 7–45
3 Format the amount

Convert CKB amounts without losing precision

ckbToHex() converts the entered CKB amount into the exact hexadecimal shannon value expected by Fiber RPC. It uses BigInt to avoid floating-point rounding across CKB's eight decimal places.

CKB amount499 CKB
Smallest unit49,900,000,000 shannons
Hexadecimal RPC value0xb9e0ab300
lib/amounts.ts · lines 1–18
4 Commit funds

Open the channel

openCkbChannel() begins channel negotiation with the connected public peer. It calls node.openChannel() with the peer pubkey, the exact funding amount, and public: true.

Its temporary channel ID confirms negotiation started; it does not mean the channel can carry a payment yet.

lib/channel.ts · lines 7–19
5 Observe confirmation

Wait for ChannelReady

watchChannelStates() keeps payment controls locked until the funding transaction and peer handshake complete. It polls listChannels() and reports each new state_name as the channel moves through the following states:

NegotiatingFunding → agree on channel parametersCollaboratingFundingTx → build the funding transactionAwaitingChannelReady → wait for confirmation and both peersChannelReady → allow payments
lib/channel.ts · lines 21–40
6 Pay and verify

Send and confirm the keysend payment

sendKeysend() sends a direct payment without first requesting an invoice. Fiber calls this a keysend payment because it does not require the receiving peer to create an invoice. The function calls sendPayment() with the recipient pubkey, amount, and keysend: true.

If the response is still in flight, waitForPayment() waits for Success or Failed. The demo then shows the payment hash and the channel's local balance before and after.

lib/payment.ts · lines 4–26
7 React integration

Wire the complete flow into React

PayPage() turns SDK state into a guided interface. It keeps the node in a ref, renders funding and channel state from React state, and gates each state-changing button on the prerequisite it needs.

Production requirements

A production product should also encrypt keys, support backup and recovery, surface fees and timeouts, and use server-side verification when payments unlock orders or access.

app/pay/page.tsx · lines 16–65
Optional local setup

Run the complete project locally

Select Download project in the top-right corner, or download here. The archive contains the Next.js application, Fiber integration, required browser headers, and the interface shown here.

Terminal
npm install
npm run dev

Then open http://localhost:3000/pay in your browser.