mwck-js/examples/wallet-watcher/main.js
2023-09-15 21:15:34 +00:00

147 lines
4.6 KiB
JavaScript

const { MempoolWallet } = Mwck;
const wallet = new MempoolWallet({
hostname: 'localhost:4200',
secure: false,
});
window.wallet = wallet;
const addressMap = {};
const addressList = [];
const regexAddress = /^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[A-z]{2,5}1[a-zA-HJ-NP-Z0-9]{39,59}|04[a-fA-F0-9]{128}|(02|03)[a-fA-F0-9]{64})$/;
const addressInput = document.getElementById('addressInput');
wallet.subscribe('addressReady', ({ address, state }) => {
updateTableRow(address);
});
wallet.subscribe('txEvent', ({event, address, tx}) => {
updateTableRow(address);
});
wallet.connect();
function trackAddress(address) {
if (regexAddress.test(address)) {
if (!addressMap[address]) {
addressMap[address] = true;
addTableRow(address);
addressList.push(address);
wallet.trackAddresses([address]);
}
return true;
} else {
alert(`${address} is not a valid bitcoin address!`);
return false;
}
}
function onTrackAddress(event) {
const address = addressInput.value
if (trackAddress(address)) {
addressInput.value = '';
}
}
function addTableRow(address) {
const table = document.getElementById('addressTable');
if (addressList.length === 0) {
table.classList.remove('hidden');
}
const newRow = document.createElement('tr');
const newCell = document.createElement('td');
newCell.textContent = address;
newRow.appendChild(newCell);
for (let i = 0; i < 3; i++) {
newRow.appendChild(document.createElement('td'));
}
table.querySelector('tbody').appendChild(newRow);
}
function updateTableRow(address) {
const table = document.getElementById('addressTable');
const i = addressList.indexOf(address);
const addressData = wallet.getAddressState(address);
const rows = table.querySelector('tbody').getElementsByTagName('tr');
const row = rows[i];
const cells = row.getElementsByTagName('td');
if (addressData && addressData.ready) {
const prevBalance = Number(cells[1].textContent.slice(0, -4)) * 100_000_000;
cells[1].textContent = `${(addressData.balance.total / 100_000_000).toFixed(8)} BTC`;
cells[2].textContent = `${addressData.transactions.length}`;
cells[3].textContent = `${addressData.utxos.length}`;
if (prevBalance != null && !isNaN(prevBalance) && addressData.balance.total && !row.className) {
if (prevBalance < addressData.balance.total) {
row.classList.add("credit");
row.classList.add("flash-once");
} else if (prevBalance > addressData.balance.total) {
row.classList.add("debit");
row.classList.add("flash-once");
} else {
row.classList.add("conf");
row.classList.add("flash-once");
}
let onAnimationEnd = () => {
row.className = "";
row.removeEventListener("animationend", onAnimationEnd);
}
row.addEventListener("animationend", onAnimationEnd);
}
}
}
function saveState() {
const state = wallet.getWalletState();
const openRequest = indexedDB.open('walletWatcher', 1);
openRequest.onupgradeneeded = function(event) {
const db = event.target.result;
db.createObjectStore('objects');
};
document.getElementById('saveButton').textContent = '...';
openRequest.onsuccess = function(event) {
const db = event.target.result;
const transaction = db.transaction(['objects'], 'readwrite');
const objectStore = transaction.objectStore('objects');
objectStore.put(JSON.stringify(state), 'addressState');
document.getElementById('saveButton').textContent = 'Save';
};
}
function restoreState() {
const openRequest = indexedDB.open('walletWatcher', 1);
openRequest.onupgradeneeded = function(event) {
const db = event.target.result;
db.createObjectStore('objects');
};
openRequest.onsuccess = function(event) {
const db = event.target.result;
const transaction = db.transaction(['objects'], 'readonly');
const objectStore = transaction.objectStore('objects');
const request = objectStore.get('addressState');
request.onsuccess = function(event) {
const state = JSON.parse(event.target.result);
if (state && state.addresses) {
for (const address of Object.keys(state.addresses)) {
if (regexAddress.test(address) && !addressMap[address]) {
addressMap[address] = true;
addTableRow(address);
addressList.push(address);
}
}
wallet.restore(state);
}
};
};
}
document.getElementById('watchButton').addEventListener('click', onTrackAddress);
document.getElementById('saveButton').addEventListener('click', saveState);
document.getElementById('restoreButton').addEventListener('click', restoreState);