Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3dfb2b1
feat(demos): add pure HTML demo for <bc-pay-button> covering all argu…
Dunsin-cyber May 20, 2025
b06d825
feat(demos/html): add pure HTML demo for <bc-connect>
Dunsin-cyber May 20, 2025
ba7edae
feat(demos/html): add pure HTML demo for <bc-button>
Dunsin-cyber May 20, 2025
209c970
fix(demos/html/bc-button): changed version to latest
Dunsin-cyber May 20, 2025
7b173af
feat(demos/html): add pure HTML demo for <bc-payment>
Dunsin-cyber May 20, 2025
c8b220b
docs(readme): update instructions for running HTML demos
Dunsin-cyber May 21, 2025
bb65b22
chore(demos/html) : remove bc-payment.html
Dunsin-cyber May 22, 2025
6369e7c
chore(demos/html) : remove bc-connect.html
Dunsin-cyber May 22, 2025
e31dc54
chore: point dev script to bc-api-usage.html
Dunsin-cyber May 23, 2025
adc3aa2
feat(demos/html): make bc-pay-button demo functional with payment tests
Dunsin-cyber May 23, 2025
6d31f32
feat(demos/html): add bc-api-usage.html for programmatic Bitcoin Connect
Dunsin-cyber May 23, 2025
f1c694e
updated README
Dunsin-cyber May 23, 2025
7d9a07b
chore(demos/html): improve README and package.json to reference demo …
Dunsin-cyber May 28, 2025
dda9349
fix : remove index.html and update README/package.json to reflect chn…
Dunsin-cyber Jun 2, 2025
2fc8ec5
chore: add disconnect button
rolznz Jun 17, 2025
732d30e
fix (demos/html) : remove manual-payment-modal from api-usage example
Dunsin-cyber Jun 17, 2025
bca467f
fix (demos/hmtl) : use setAttribute to set preimage in bc-pay-button
Dunsin-cyber Jun 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 46 additions & 8 deletions demos/html/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,53 @@
# demos/html
# `demos/html`

A simple example of how to add Bitcoin Connect to a simple HTML website
A simple demo showcasing how to use **Bitcoin Connect** web components in plain HTML.

Simply open [index.html](./index.html) in your browser
### Included Components

## Watching for changes
<!-- * `<bc-button />` – Launches the wallet connection modal. -->
* `<bc-pay-button />` – Opens a Lightning payment modal with a BOLT11 invoice.

### Install

Run `yarn install`
---

## Previewing the Demos

### Option 1: Open HTML Files Directly

You can open any of the demo files in your browser by double-clicking or using “Open with Browser”:

* [`bc-api-usage.html`](./bc-api-usage.html)
* [`bc-pay-button.html`](./bc-pay-button.html)
<!-- * [`bc-connect.html`](./bc-connect.html)
* [`bc-payment.html`](./bc-payment.html) -->

---

### Option 2: Run a Local Development Server

We recommend using a local server for hot reloading and better cross-origin behavior (especially for web components and modules).

#### 1. Install dependencies

```bash
yarn install
```

#### 2. Start the dev server

```bash
yarn dev
```

This will:

* Start a dev server using [`@web/dev-server`](https://modern-web.dev/docs/dev-server/overview/).
* Open `bc-api-usage.html` automatically in your default browser.
* Watch for changes in the repo and reload the page live.

To preview other demo files, manually open them in your browser:


* [bc-pay-button.html](http://localhost:8000/demos/html/bc-pay-button.html)

### Development

Run `yarn dev`
175 changes: 175 additions & 0 deletions demos/html/bc-api-usage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>bc-api-usage Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* Basic styling for a clean demo interface */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
background: #f5f5f5;
min-height: 100vh;
box-sizing: border-box;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
max-width: 500px;
width: 100%;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
h1 {
margin-top: 0;
font-size: 24px;
}
button {
display: block;
width: 100%;
padding: 12px;
margin-bottom: 10px;
background: #4f46e5;
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background: #4338ca;
}
</style>
</head>
<body>
<div class="container">
<h1>Programmatic Access Demo</h1>
<!-- Demo buttons showing different API capabilities -->
<button id="request-provider">Request provider</button>
<button id="launch-modal">Open modal</button>
<button id="launch-modal-pay-invoice">Open modal to pay invoice</button>
<button id="launch-modal-pay-invoice-lnurl-verify">
LNURL-verify payment
</button>
</div>

<script type="module">
// Import required Bitcoin Connect functions and Lightning Tools
import {
init,
launchModal,
launchPaymentModal,
requestProvider,
} from 'https://esm.sh/@getalby/bitcoin-connect@latest';
import {LightningAddress} from 'https://esm.sh/@getalby/lightning-tools@latest';

// Initialize Bitcoin Connect with your app name
init({appName: 'Programmatic Access Demo'});

// Payment methods configuration: can be "all" | "external" | "internal"
const paymentMethods = 'all';

// ==============================================
// 1. Basic Provider Detection
// ==============================================
document
.getElementById('request-provider')
.addEventListener('click', async () => {
try {
// Attempt to detect a WebLN provider (like Alby extension)
const provider = await requestProvider();
console.log('WebLN provider: ', provider);
alert('WebLN provider available');
} catch (error) {
console.error('Failed to request provider:', error);
alert('Failed to request provider');
}
});

// ==============================================
// 2. Basic Modal Launch
// ==============================================
document.getElementById('launch-modal').addEventListener('click', () => {
// Opens the default Bitcoin Connect modal
launchModal();
});

// ==============================================
// 3. Payment Modal with Manual Invoice Entry
// ==============================================
//! only payment made within the modal will be detected
document
.getElementById('launch-modal-pay-invoice')
.addEventListener('click', () => {
// Check for a stored invoice or prompt the user
const invoice = localStorage.getItem('invoice');
const invoiceToPay = invoice || window.prompt('paste invoice');

if (!invoiceToPay) {
alert('No invoice provided');
return;
}

// Launch payment modal with custom handlers
launchPaymentModal({
invoice: invoiceToPay,
paymentMethods,
onPaid: (response) => {
alert('Paid! ' + response.preimage);
},
onCancelled: () => {
alert('Payment cancelled');
},
});
});

// ==============================================
// 4. Payment with LNURL Verification
// ==============================================
document
.getElementById('launch-modal-pay-invoice-lnurl-verify')
.addEventListener('click', async () => {
// Create a Lightning Address instance
const ln = new LightningAddress('[email protected]');
await ln.fetch(); // Fetch LNURL metadata

// Request a new invoice for 1 satoshi
const invoice = await ln.requestInvoice({satoshi: 1});

// Launch payment modal with enhanced verification
const {setPaid} = launchPaymentModal({
invoice: invoice.paymentRequest,
paymentMethods,
onPaid: (response) => {
console.log('Received payment! ' + response.preimage);
clearInterval(checkPaymentInterval);
},
onCancelled: () => {
clearInterval(checkPaymentInterval);
alert('Payment cancelled');
},
});

// Set up payment verification polling
// This checks every second if invoice was paid externally
const checkPaymentInterval = setInterval(async () => {
try {
const paid = await invoice.verifyPayment();
if (paid) {
// Update modal state if payment is detected
setPaid({
preimage: invoice.preimage,
});
}
} catch (error) {
console.error('Verification error:', error);
}
}, 1000);
});
</script>
</body>
</html>
21 changes: 21 additions & 0 deletions demos/html/bc-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<title>bc-button Demo</title>
<script type="module">
import {onConnected} from 'https://esm.sh/@getalby/bitcoin-connect@latest';
onConnected((provider) => {
console.log('Connected with provider', provider);
});
</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div style="display: flex; flex-direction: column; gap: 1rem">
<code> &lt;bc-button /&gt; Demo</code>
<bc-button></bc-button>
</div>
</body>
</html>
71 changes: 71 additions & 0 deletions demos/html/bc-pay-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>bc-pay-button Demo</title>

<script type="module">
// Import necessary modules from esm.sh CDN
import {init} from 'https://esm.sh/@getalby/bitcoin-connect@latest';
import {LightningAddress} from 'https://esm.sh/@getalby/lightning-tools@latest';

// Initialize Bitcoin Connect with your app name
// This sets up the connection to Bitcoin wallets
init({appName: 'your app name'});

// Get reference to the pay button element in the DOM
const payButton = document.getElementById('pay-button');

// Add click event listener to the pay button
payButton.addEventListener('click', async () => {
try {
// Create a new LightningAddress instance for the recipient
const ln = new LightningAddress('[email protected]');
await ln.fetch();

// Request an invoice from the Lightning address
// - satoshi: Amount to pay (1 satoshi = 0.00000001 BTC)
// - memo: Optional description of the payment
const invoice = await ln.requestInvoice({
satoshi: 1,
memo: 'bc-pay-button demo payment',
});

payButton.setAttribute('invoice', invoice.paymentRequest);

// Set up a payment verification loop
// Checks every second if payment was received
const checkPaymentInterval = setInterval(async () => {
try {
const paid = await invoice.verifyPayment();

if (paid) {
console.log('Payment received! Preimage:', invoice.preimage);
payButton._paid = true;
payButton.preimage = invoice.preimage;
payButton.requestUpdate();
clearInterval(checkPaymentInterval);
}
} catch (error) {
console.error('Verification error:', error);
clearInterval(checkPaymentInterval);
}
}, 1000);
} catch (error) {
console.error('Invoice creation failed:', error);
alert('Failed to create invoice: ' + error.message);
}
});
</script>
</head>

<body>
<!-- Simple demo layout with the pay button -->
<div style="display: flex; flex-direction: column; gap: 1rem">
<code> &lt;bc-pay-button /&gt; Demo</code>

<bc-pay-button id="pay-button" title="Pay 1 Sats"></bc-pay-button>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion demos/html/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"scripts": {
"dev": "wds -r ../.. -o ./demos/html/index.html --watch"
"dev": "wds -r ../.. -o ./demos/html/bc-api-usage.html --watch"
},
"devDependencies": {
"@web/dev-server": "^0.1.31"
Expand Down