Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
pnpm-lock.yaml

node_modules
dist
Expand Down
119 changes: 119 additions & 0 deletions javascript/html-bitcoin/css/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
:root {
--background: #ffffff;
--foreground: #171717;
}

html,
body {
overflow-x: hidden;
max-width: 100vw;
}

body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

* {
box-sizing: border-box;
padding: 0;
margin: 0;
}

a {
color: inherit;
text-decoration: none;
}

@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}

section {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 16px;
background-color: #f9f9f9;
padding: 13px;
margin: 10px;
width: 90%;
text-align: left;
}

.pages {
align-items: center;
justify-items: center;
text-align: center;
display: grid;
}

.state-container {
align-items: center;
justify-items: center;
text-align: center;
}

button {
padding: 10px 15px;
background-color: white;
color: black;
border: 2px solid black;
border-radius: 6px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin: 15px; /* Space between buttons */
}

button:hover {
background-color: black;
color: white;
}

button:active {
background-color: #333; /* Dark gray on click */
color: white;
}

h1 {
margin: 20px;
}

h2 {
padding-bottom: 6px;
}

pre {
white-space: pre-wrap; /* Wraps long lines inside <pre> */
word-break: break-all;
}


.link-button {
background-color: black;
color: white;
padding: 5px 10px;
text-decoration: none;
border-radius: 5px;
}

.link-button:hover {
background-color: #333; /* Darken the background on hover */
}

.link-button:hover {
background-color: white; /* Change background to white on hover */
color: black; /* Change text color to black on hover */
}

.advice {
text-align: 'center';
margin-bottom: 10px;
line-height: 25px;
}
76 changes: 76 additions & 0 deletions javascript/html-bitcoin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTML Bitcoin Example</title>
<link rel="stylesheet" href="css/App.css" />
</head>

<body>
<div class="pages" id="app">
<img src="/reown.svg" alt="Reown" style="width: 150px; height: 150px" />
<h1>AppKit Bitcoin VanillaJS dApp Example</h1>

<!-- AppKit UI Components -->
<div class="button-group">
<appkit-button />
</div>

<!-- Modal Controls -->
<div class="button-group">
<button id="open-connect-modal" data-connected-only>Open Connect Modal</button>
<button id="disconnect" data-connected-only>Disconnect</button>
<button id="sign-message" data-connected-only>Sign Message</button>
<button id="get-balance" data-connected-only>Get Balance</button>
</div>

<!-- State Displays -->
<section id="balanceSection" style="display: none;">
<h2>Balance</h2>
<pre id="balanceState"></pre>
</section>

<section id="txSection" style="display: none;">
<h2>Tx</h2>
<pre id="txState"></pre>
</section>

<section id="signatureSection" style="display: none;">
<h2>Signature</h2>
<pre id="signatureState"></pre>
</section>

<section>
<h2>Account</h2>
<pre id="accountState"></pre>
</section>

<section>
<h2>Network</h2>
<pre id="networkState"></pre>
</section>

<section>
<h2>Modal State</h2>
<pre id="appKitState"></pre>
</section>

<section>
<h2>Theme</h2>
<pre id="themeState"></pre>
</section>

<section>
<h2>Events</h2>
<pre id="events"></pre>
</section>

<section>
<h2>Wallet Info</h2>
<pre id="walletInfo"></pre>
</section>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
16 changes: 16 additions & 0 deletions javascript/html-bitcoin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "vanillajs-bitcoin",
"private": true,
"version": "0.0.1",
"scripts": {
"dev": "vite --port 3011",
"build": "vite build"
},
"dependencies": {
"@reown/appkit": "1.6.5",
"@reown/appkit-adapter-bitcoin": "1.6.5"
},
"devDependencies": {
"vite": "5.2.11"
}
}
Binary file added javascript/html-bitcoin/public/favicon.ico
Binary file not shown.
2 changes: 2 additions & 0 deletions javascript/html-bitcoin/public/reown.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions javascript/html-bitcoin/src/config/appKit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { bitcoin } from '@reown/appkit/networks'
import { createAppKit } from '@reown/appkit'
import { BitcoinAdapter } from '@reown/appkit-adapter-bitcoin'

const projectId = import.meta.env.VITE_PROJECT_ID
if (!projectId) {
throw new Error('VITE_PROJECT_ID is not set')
}

const bitcoinAdapter = new BitcoinAdapter({
projectId
})

export const appKit = createAppKit({
adapters: [bitcoinAdapter],
networks: [bitcoin],
projectId,
themeMode: 'light',
themeVariables: {
'--w3m-accent': '#000000',
}
})
54 changes: 54 additions & 0 deletions javascript/html-bitcoin/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { appKit } from './config/appKit'
import { store } from './store/appkitStore'
import { updateTheme, updateButtonVisibility } from './utils/dom'
import { signMessage, getBalance } from './services/wallet'
import { initializeSubscribers } from './utils/suscribers'

// Initialize subscribers
initializeSubscribers(appKit)

// Initial check
updateButtonVisibility(appKit.getIsConnectedState());

// Button event listeners
document.getElementById('open-connect-modal')?.addEventListener(
'click', () => appKit.open()
)

document.getElementById('disconnect')?.addEventListener(
'click', () => {
appKit.disconnect()
}
)

document.getElementById('sign-message')?.addEventListener(
'click', async () => {
const signature = await signMessage(store.bip122Provider, store.accountState.address)

document.getElementById('signatureState').innerHTML = signature
document.getElementById('signatureSection').style.display = ''
}
)

document.getElementById('send-tx')?.addEventListener(
'click', async () => {
console.log(store.bip122Provider, store.accountState.address)
const tx = await sendTx(store.bip122Provider, store.accountState.address)
console.log('Tx:', tx)

document.getElementById('txState').innerHTML = JSON.stringify(tx, null, 2)
document.getElementById('txSection').style.display = ''
}
)

document.getElementById('get-balance')?.addEventListener(
'click', async () => {
const balance = await getBalance(store.bip122Provider, store.accountState.address)

document.getElementById('balanceState').innerHTML = balance + ' ETH'
document.getElementById('balanceSection').style.display = ''
}
)

// Set initial theme
updateTheme(store.themeState.themeMode)
27 changes: 27 additions & 0 deletions javascript/html-bitcoin/src/services/wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@


export const signMessage = (provider, address) => {
if (!provider) return Promise.reject('No provider available')

console.log("provider", provider.signMessage)
return provider.signMessage({
message: 'Hello from AppKit!',
address: address
})
}

export const getBalance = async (provider, address) => {
if (!provider) return Promise.reject('No provider available')

// get the utxos ... this is the list of unspent transactions that the sender has
const utxos = await getUTXOs(address, false)
// return the sum of the utxos ... The balance of the sender
return utxos.reduce((sum, utxo) => sum + utxo.value, 0)
}

const getUTXOs = async (address) => {
const response = await fetch(
`https://mempool.space/api/address/${address}/utxo`
)
return await response.json();
}
13 changes: 13 additions & 0 deletions javascript/html-bitcoin/src/store/appkitStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const store = {
accountState: {},
networkState: {},
appKitState: {},
themeState: { themeMode: 'light', themeVariables: {} },
events: [],
walletInfo: {},
bip122Provider: null
}

export const updateStore = (key, value) => {
store[key] = value
}
19 changes: 19 additions & 0 deletions javascript/html-bitcoin/src/utils/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const updateStateDisplay = (elementId, state) => {
const element = document.getElementById(elementId)
if (element) {
element.innerHTML = JSON.stringify(state, null, 2)
}
}

export const updateTheme = mode => {
document.documentElement.setAttribute('data-theme', mode)
document.body.className = mode
}

export const updateButtonVisibility = (isConnected) => {
const connectedOnlyButtons = document.querySelectorAll('[data-connected-only]')
connectedOnlyButtons.forEach(button => {
if (!isConnected) button.style.display = 'none'
else button.style.display = ''
})
}
25 changes: 25 additions & 0 deletions javascript/html-bitcoin/src/utils/suscribers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { store, updateStore } from '../store/appkitStore'
import { updateStateDisplay, updateTheme, updateButtonVisibility } from '../utils/dom'
import { polygon, mainnet } from '@reown/appkit/networks'

export const initializeSubscribers = (modal) => {
modal.subscribeProviders(state => {
updateStore('bip122Provider', state['bip122'])
})

modal.subscribeAccount(state => {
updateStore('accountState', state)
updateStateDisplay('accountState', state)
})

modal.subscribeNetwork(state => {
updateStore('networkState', state)
updateStateDisplay('networkState', state)
})

modal.subscribeState(state => {
store.appKitState = state

updateButtonVisibility(modal.getIsConnectedState())
})
}
Loading