Skip to main content

Chain picker

The HelaMesh SDK ships a pre-styled chain picker component that renders a clickable list of the chains your client supports. Drop it into any page and your customers choose which network to pay with โ€” your code creates the invoice for that specific chain after they pick.

The flowโ€‹

  1. Customer hits your checkout page. You render the chain picker.
  2. SDK fetches available chains from /v1/chains/client/:id?pk=....
  3. Customer clicks a chain โ€” SDK fires your onSelect(network) callback.
  4. Your backend creates an invoice locked to that network.
  5. You redirect or mount the HelaMesh embed for the newly created invoice.

HTML / vanilla JSโ€‹

checkout.html
<script src="https://pay.helamesh.com/sdk/v1.js"></script>

<div id="chain-picker"></div>
<div id="checkout"></div>

<script>
HelaMesh.renderChainPicker('#chain-picker', {
clientId: 'YOUR_CLIENT_ID',
publishableKey: 'pk_test_YOUR_KEY',
onSelect: async (network, chain) => {
console.log('Customer picked:', network);

// Call YOUR backend to create the invoice with the chosen network.
// This keeps your secret API key on the server where it belongs.
const res = await fetch('/api/create-invoice', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ amount: 25, network }),
});
const { invoiceId } = await res.json();

// Now mount the checkout embed for the new invoice
HelaMesh.mount('#checkout', {
invoiceId,
publishableKey: 'pk_test_YOUR_KEY',
onPaid: (event) => {
window.location.href = '/order/success';
},
});
},
});
</script>

Reactโ€‹

ChainPicker.tsx
import { useEffect, useRef } from 'react';

declare global {
interface Window {
HelaMesh?: any;
}
}

export function CheckoutWithPicker({ amount }: { amount: number }) {
const pickerRef = useRef<HTMLDivElement>(null);
const checkoutRef = useRef<HTMLDivElement>(null);

useEffect(() => {
let pickerInstance: any = null;
let embedInstance: any = null;

const tryRender = () => {
if (!window.HelaMesh || !pickerRef.current) return false;
pickerInstance = window.HelaMesh.renderChainPicker(pickerRef.current, {
clientId: process.env.NEXT_PUBLIC_HELAMESH_CLIENT_ID!,
publishableKey: process.env.NEXT_PUBLIC_HELAMESH_PK!,
onSelect: async (network: string) => {
// Hit your own backend to create the invoice
const res = await fetch('/api/create-invoice', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ amount, network }),
});
const { invoiceId } = await res.json();

// Tear down the picker, mount the checkout
pickerInstance?.destroy();
if (checkoutRef.current) {
embedInstance = window.HelaMesh.mount(checkoutRef.current, {
invoiceId,
publishableKey: process.env.NEXT_PUBLIC_HELAMESH_PK!,
onPaid: () => window.location.href = '/order/success',
});
}
},
});
return true;
};

if (!tryRender()) {
const script = document.createElement('script');
script.src = 'https://pay.helamesh.com/sdk/v1.js';
script.async = true;
script.onload = tryRender;
document.body.appendChild(script);
}

return () => {
pickerInstance?.destroy();
embedInstance?.destroy();
};
}, [amount]);

return (
<div>
<div ref={pickerRef} />
<div ref={checkoutRef} style={{ marginTop: 20 }} />
</div>
);
}
Create the invoice on your backend

Create the invoice on your backend, not in the browser. The secret hm_* API key must stay server-side. The browser only uses the publishable pk_* key for reading chain lists and rendering the embed.