damus.io

damus.io website
git clone git://jb55.com/damus.io
Log | Files | Refs | README | LICENSE

tipjar.js (4536B)


      1 async function make_request(method, rune, params) {
      2 	const LNSocket = await lnsocket_init()
      3 	const ln = LNSocket()
      4 
      5 	ln.genkey()
      6 	await ln.connect_and_init("03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71", "wss://cln.jb55.com:443")
      7 
      8 	const {result} = await ln.rpc({ rune, method, params })
      9 
     10 	ln.disconnect()
     11 	return result
     12 }
     13 
     14 function fetch_tipjar_summary() {
     15 	const rune = "5sgpXcVRMy19h2Ai9LiklJ7jI_J3qNnnG36wvyViqR49OTQmbWV0aG9kPW9mZmVyLXN1bW1hcnkmcG5hbWVkZXNjcmlwdGlvbj1AZGFtdXMtYW5kcm9pZCZwbmFtZWxpbWl0PTU="
     16 	return make_request("offer-summary", rune, {
     17 		offerid: "2043536dfec68d559102f73510927622812a230cfdda079e96fccbfe35a96d11",
     18 		description: "@damus-android",
     19 		limit: 5
     20 	})
     21 }
     22 
     23 function make_invoice(description) {
     24 	const rune = "LZwGZJO7wZgmoScFQb5reZ0Ii8qPKCeUfTb-UcbDxWw9MTImbWV0aG9kPWludm9pY2U="
     25 	description = (description && `${description} @damus-android`) || "@damus-android donation"
     26 	return make_request("invoice", rune, {
     27 		amount_msat: "any",
     28 		label: `damus-android-${new Date().getTime()}`,
     29 		description: description
     30 	})
     31 }
     32 
     33 function make_qrcode(dat) {
     34 	const link = dat.toUpperCase()
     35 	document.querySelector("#qrcode").innerHTML = ""
     36 	const qr = new QRCode("qrcode", {
     37 		text: link,
     38 		width: 256,
     39 		height: 256,
     40 		colorDark : "#000000",
     41 		colorLight : "#ffffff",
     42 		correctLevel : QRCode.CorrectLevel.L
     43 	})
     44 }
     45 
     46 async function click_make_invoice(el) {
     47 	const offerdata = document.querySelector("#offerdata")
     48 	const tipjar_img = document.querySelector("#tipjar-offer-qr")
     49 
     50 	const note = prompt("Leave a note!", "")
     51 
     52 	const invoice = await make_invoice(note)
     53 
     54 	make_qrcode("LIGHTNING:" + invoice.bolt11)
     55 	document.querySelector("#bolt12").href = "lightning:" + invoice.bolt11
     56 
     57 	el.style.display = "none";
     58 }
     59 
     60 async function copy_tip() {
     61 	const offer = document.querySelector("#offerdata").value.trim();
     62 	try {
     63 		await navigator.clipboard.writeText(offer)
     64 		alert("Invoice copied to clipboard!")
     65 	} catch(err) {
     66 		console.log("clipboard copy error", err)
     67 		document.querySelector("#offerdata").style.display = "block"
     68 	}
     69 }
     70 
     71 async function go() {
     72 	const summary = await fetch_tipjar_summary()
     73 
     74 	const el = document.querySelector("#tipjar-summary")
     75 	const bolt12 = document.querySelector("#bolt12")
     76 
     77 	make_qrcode(bolt12.href)
     78 	el.innerHTML = render_tips(summary)
     79 }
     80 
     81 function render_tips(res) {
     82 	const total_sats = res.total_msatoshi / 1000
     83 	const goal = 3000000
     84 	const perc = `${((total_sats / goal) * 100).toPrecision(2)}%`
     85 	const total_fmt = `${format_amount(total_sats)} / ${format_amount(goal)} sats goal (${perc})`
     86 	return `
     87 	<p>Total: <b>${total_fmt}</b></p>
     88 	<div class="progres" style="height:20px; background-color: #f1f1f1">
     89 		<div class="progress-bar" style="background-color: #f44336; height: 100%;width: ${perc}"></div>
     90 	</div>
     91 	<h5>Recent Donors</h5>
     92 	${render_table(res.paid_invoices)}
     93 	<h5>Top Donors</h5>
     94 	${render_table(res.top_donors)}
     95 	`
     96 }
     97 
     98 function render_table(invoices)
     99 {
    100 	return `
    101 	<table style="width: 100%">
    102 	<thead>
    103 		<tr>
    104 			<th>Note</th>
    105 			<th>Amount</th>
    106 			<th></th>
    107 		</tr>
    108 	</thead>
    109 	<tbody>
    110 	  ${invoices.map(render_tip).join("\n")}
    111 	</tbody>
    112 	</table>
    113 	`
    114 }
    115 
    116 function format_amount(amt)
    117 {
    118 	return amt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    119 }
    120 
    121 function render_tip(tip)
    122 {
    123 	let note = tip.payer_note ? tip.payer_note : (tip.description || "Anonymous")
    124 	note = note.replace("@damus-android", "")
    125 	const amount = format_amount(tip.amount_msat / 1000)
    126 	const now = Math.floor(new Date().getTime() / 1000)
    127 	const date = time_delta(now * 1000, tip.paid_at * 1000)
    128 
    129 	return `
    130 	<tr>
    131 		<td>${note}</td>
    132 		<td>${amount} sats</td>
    133 		<td class="reldate">${date}</td>
    134 	</tr>
    135 	`
    136 }
    137 
    138 function time_delta(current, previous) {
    139     var msPerMinute = 60 * 1000;
    140     var msPerHour = msPerMinute * 60;
    141     var msPerDay = msPerHour * 24;
    142     var msPerMonth = msPerDay * 30;
    143     var msPerYear = msPerDay * 365;
    144 
    145     var elapsed = current - previous;
    146 
    147     if (elapsed < msPerMinute) {
    148          return Math.round(elapsed/1000) + ' seconds ago';   
    149     }
    150 
    151     else if (elapsed < msPerHour) {
    152          return Math.round(elapsed/msPerMinute) + ' minutes ago';   
    153     }
    154 
    155     else if (elapsed < msPerDay ) {
    156          return Math.round(elapsed/msPerHour ) + ' hours ago';   
    157     }
    158 
    159     else if (elapsed < msPerMonth) {
    160         return Math.round(elapsed/msPerDay) + ' days ago';   
    161     }
    162 
    163     else if (elapsed < msPerYear) {
    164         return Math.round(elapsed/msPerMonth) + ' months ago';   
    165     }
    166 
    167     else {
    168         return Math.round(elapsed/msPerYear ) + ' years ago';   
    169     }
    170 }
    171 
    172 go()