diff --git a/assets/lntip.js b/assets/lntip.js deleted file mode 100644 index d261516..0000000 --- a/assets/lntip.js +++ /dev/null @@ -1,151 +0,0 @@ -/*! https://github.com/robiveli/jpopup */ -!function(e,n){void 0===e&&void 0!==window&&(e=window),"function"==typeof define&&define.amd?define([],function(){return e.jPopup=n()}):"object"==typeof module&&module.exports?module.exports=n():e.jPopup=n()}(this,function(){"use strict";var n,o,t=function(){var e=0\n \n
'.concat(e,"
\n ")))},s=function(e){1==e?window.location.hash=o:window.history.back()},d=function(e){27==e.keyCode&&t.prototype.close(!0)},c=function(){window.location.hash!==o&&t.prototype.close(!1)},a=function(){document.getElementsByClassName("jCloseBtn")[0].addEventListener("click",function(){t.prototype.close(!0)}),window.addEventListener("keydown",d),1==n&&window.addEventListener("hashchange",c)},u=document.querySelector("html");return t.prototype={close:function(e){u.classList.add("jPopupClosed"),1==n&&(e&&s(!1),window.removeEventListener("hashchange",c)),window.removeEventListener("keydown",d),document.getElementsByClassName("jPopup")[0].addEventListener("animationend",function(e){e.target.parentNode.removeChild(this),u.classList.remove("jPopupClosed"),u.classList.remove("jPopupOpen")})},open:function(e){t(e)}},t}); - -LnTip = function (options) { - var host = document.getElementById('lntip-script').getAttribute('lntip-host'); - this.host = options.host || host; - this.value = options.value; - this.memo = options.memo || ''; - this.loadStylesheet(); // load it early that styles are ready when the popup is opened -} - -LnTip.prototype.loadStylesheet = function () { - if (document.getElementById('lntip-style')) { return; } - // get the CSS file from the same source as the JS widget file - var script = document.getElementById('lntip-script'); - var source = script.src.replace(/\.js$/, ".css"); - var head = document.getElementsByTagName('head')[0]; - var css = document.createElement('link'); - css.id = "lntip-style"; - css.rel = "stylesheet"; - css.type = "text/css"; - css.href = source - head.appendChild(css); -} - -LnTip.prototype.closePopup = function () { - if (this.popup) { - this.popup.close(); - this.popup = null; - } -} - -LnTip.prototype.openPopup = function (content) { - this.closePopup(); - this.popup = new jPopup({ - content: content, - shouldSetHash: false - }); - return this.popup; -} - -LnTip.prototype.thanks = function () { - var content = '

Thank you!

'; - this.openPopup(content); - setTimeout(() => { - this.closePopup(); - }, 3000); -} - -LnTip.prototype.watchPayment = function () { - if (this.paymentWatcher) { window.clearInterval(this.paymentWatcher) } - - return new Promise((resolve, reject) => { - this.paymentWatcher = window.setInterval(() => { - this._fetch(`${this.host}/v1/invoice/${this.invoice.ImplDepID}`) - .then((invoice) => { - if (invoice.settled) { - this.invoice.settled = true; - this.stopWatchingPayment(); - resolve(this.invoice); - } - }); - }, 2000); - }); -} - -LnTip.prototype.stopWatchingPayment = function () { - window.clearInterval(this.paymentWatcher); - this.paymentWatcher = null; -} - -LnTip.prototype.payWithWebln = function () { - if (!webln.isEnabled) { - webln.enable().then((weblnResponse) => { - return webln.sendPayment({ paymentRequest: this.invoice.payment_request }) - }).catch((e) => { - return this.showPaymentRequest(); - }) - } else { - return webln.sendPayment({ paymentRequest: this.invoice.payment_request }) - } -} - -LnTip.prototype.showPaymentRequest = function () { - var content = `
-

${this.memo}

-

${this.value} satoshi

-
- -
- -
` - this.openPopup(content); - - document.getElementById('lntip-copy').onclick = () => { - navigator.clipboard.writeText(this.invoice.payment_request); - alert('Copied to clipboad'); - } - return Promise.resolve(); // be compatible to payWithWebln() -} - -LnTip.prototype.addInvoice = function () { - var args = { - method: 'POST', - mode: 'cors', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ memo: this.memo, value: this.value }) - }; - return this._fetch( - `${this.host}/v1/invoices`, - args - ).then((invoice) => { - this.invoice = invoice; - return invoice; - }); -} - -LnTip.prototype.requestPayment = function () { - return this.addInvoice().then((invoice) => { - if (typeof webln !== 'undefined') { - return this.payWithWebln(); - } else { - return this.showPaymentRequest(); - } - }); -} - -LnTip.prototype.request = function () { - return this.requestPayment().then(() => { - this.watchPayment().then((invoice) => { - this.thanks(); - }); - }); -} - -LnTip.prototype._fetch = function(url, args) { - return fetch(url, args).then((response) => { - if (response.ok) { - return response.json(); - } else { - throw new Error(response); - } - }) -} diff --git a/assets/lntip.css b/files/assets/lnme.css similarity index 93% rename from assets/lntip.css rename to files/assets/lnme.css index 0184de0..59f39ad 100644 --- a/assets/lntip.css +++ b/files/assets/lnme.css @@ -4,21 +4,21 @@ z-index:10000; } -.lntip-payment-request { +.jPopup .lnme-payment-request { width: 220px; margin: 0 auto; text-align: center; } -.lntip-payment-request h1, .lntip-payment-request h2 { +.jPopup .lnme-payment-request h1, .jPopup .lnme-payment-request h2 { text-align: center; } -.lntip-details { +.jPopup .lnme-details { width: 200px; overflow: hidden; } -.lntip-copy { +.jPopup .lnme-copy { cursor: pointer; display: inline; } diff --git a/files/assets/lnme.js b/files/assets/lnme.js new file mode 100644 index 0000000..5454620 --- /dev/null +++ b/files/assets/lnme.js @@ -0,0 +1,204 @@ +/*! https://github.com/robiveli/jpopup */ +!function(e,n){void 0===e&&void 0!==window&&(e=window),"function"==typeof define&&define.amd?define([],function(){return e.jPopup=n()}):"object"==typeof module&&module.exports?module.exports=n():e.jPopup=n()}(this,function(){"use strict";var n,o,t=function(){var e=0\n \n
'.concat(e,"
\n ")))},s=function(e){1==e?window.location.hash=o:window.history.back()},d=function(e){27==e.keyCode&&t.prototype.close(!0)},c=function(){window.location.hash!==o&&t.prototype.close(!1)},a=function(){document.getElementsByClassName("jCloseBtn")[0].addEventListener("click",function(){t.prototype.close(!0)}),window.addEventListener("keydown",d),1==n&&window.addEventListener("hashchange",c)},u=document.querySelector("html");return t.prototype={close:function(e){u.classList.add("jPopupClosed"),1==n&&(e&&s(!1),window.removeEventListener("hashchange",c)),window.removeEventListener("keydown",d),document.getElementsByClassName("jPopup")[0].addEventListener("animationend",function(e){e.target.parentNode.removeChild(this),u.classList.remove("jPopupClosed"),u.classList.remove("jPopupOpen")})},open:function(e){t(e)}},t}); + +/* + https://github.com/nimiq/qr-creator + jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */ +'use strict';let G=null;class H{}H.render=function(w,B){G(w,B)};self.QrCreator=H; +(function(w){function B(t,c,a,e){var b={},h=w(a,c);h.u(t);h.J();e=e||0;var r=h.h(),d=h.h()+2*e;b.text=t;b.level=c;b.version=a;b.O=d;b.a=function(b,a){b-=e;a-=e;return 0>b||b>=r||0>a||a>=r?!1:h.a(b,a)};return b}function C(t,c,a,e,b,h,r,d,g,x){function u(b,a,f,c,d,r,g){b?(t.lineTo(a+r,f+g),t.arcTo(a,f,c,d,h)):t.lineTo(a,f)}r?t.moveTo(c+h,a):t.moveTo(c,a);u(d,e,a,e,b,-h,0);u(g,e,b,c,b,0,-h);u(x,c,b,c,a,h,0);u(r,c,a,e,a,0,h)}function z(t,c,a,e,b,h,r,d,g,x){function u(b,a,c,d){t.moveTo(b+c,a);t.lineTo(b, +a);t.lineTo(b,a+d);t.arcTo(b,a,b+c,a,h)}r&&u(c,a,h,h);d&&u(e,a,-h,h);g&&u(e,b,-h,-h);x&&u(c,b,h,-h)}function A(t,c){var a=c.fill;if("string"===typeof a)t.fillStyle=a;else{var e=a.type,b=a.colorStops;a=a.position.map((b)=>Math.round(b*c.size));if("linear-gradient"===e)var h=t.createLinearGradient.apply(t,a);else if("radial-gradient"===e)h=t.createRadialGradient.apply(t,a);else throw Error("Unsupported fill");b.forEach(([b,a])=>{h.addColorStop(b,a)});t.fillStyle=h}}function y(t,c){a:{var a=c.text,e= +c.v,b=c.N,h=c.K,r=c.P;b=Math.max(1,b||1);for(h=Math.min(40,h||40);b<=h;b+=1)try{var d=B(a,e,b,r);break a}catch(J){}d=void 0}if(!d)return null;a=t.getContext("2d");c.background&&(a.fillStyle=c.background,a.fillRect(c.left,c.top,c.size,c.size));e=d.O;h=c.size/e;a.beginPath();for(r=0;r>>7-b%8&1)},put:function(b,h){for(var a=0;a>>h-a-1&1))},f:function(){return a},m:function(b){var h=Math.floor(a/8);c.length<=h&&c.push(0);b&&(c[h]|=128>>>a%8);a+=1}};return e}function C(c,a){function e(b,h){for(var a=-1;7>=a;a+=1)if(!(-1>=b+a||d<=b+a))for(var c=-1;7>=c;c+=1)-1>=h+c||d<=h+c||(r[b+a][h+c]=0<=a&&6>=a&&(0==c||6==c)||0<=c&&6>=c&&(0==a||6==a)||2<=a&&4>=a&&2<=c&&4>=c?!0:!1)}function b(b,a){for(var f=d=4*c+17,k=Array(f),m=0;m< +f;m+=1){k[m]=Array(f);for(var p=0;p=n;n+=1)for(var l=-2;2>=l;l+=1)r[p+n][q+l]=-2==n||2==n||-2==l||2==l||0==n&&0==l}for(f=8;fk;k+=1)m=!b&&1==(f>>k&1),r[6>k?k:8>k?k+1:d-15+k][8]=m,r[8][8>k?d-k-1:9>k?15-k:14-k]=m;r[d-8][8]=!b;if(7<= +c){f=y.A(c);for(k=0;18>k;k+=1)m=!b&&1==(f>>k&1),r[Math.floor(k/3)][k%3+d-8-3]=m;for(k=0;18>k;k+=1)m=!b&&1==(f>>k&1),r[k%3+d-8-3][Math.floor(k/3)]=m}if(null==g){b=t.I(c,h);f=B();for(k=0;k8*m)throw Error("code length overflow. ("+f.f()+">"+8*m+")");for(f.f()+4<=8*m&&f.put(0,4);0!=f.f()%8;)f.m(!1);for(;!(f.f()>=8*m);){f.put(236,8);if(f.f()>=8*m)break;f.put(17,8)}var u=0;m=k=0;p=Array(b.length); +q=Array(b.length);for(n=0;nn;n+=1)null==r[k][q-n]&&(l=!1,p>>m&1)),a(k,q-n)&&(l=!l),r[k][q-n]=l,--m,-1==m&&(p+=1,m=7));k+=f;if(0>k||d<=k){k-=f;f=-f;break}}}var h=A[a],r=null,d=0,g=null,x=[],u={u:function(b){b=w(b);x.push(b);g=null},a:function(b,a){if(0>b||d<=b||0>a||d<=a)throw Error(b+","+a);return r[b][a]},h:function(){return d},J:function(){for(var a=0,h=0,c=0;8>c;c+=1){b(!0,c);var d=y.D(u);if(0==c||a>d)a=d,h=c}b(!1,h)}};return u} +function z(c,a){if("undefined"==typeof c.length)throw Error(c.length+"/"+a);var e=function(){for(var b=0;bb.b()-a.b())return b;for(var c=v.g(b.c(0))-v.g(a.c(0)),h=Array(b.b()), +g=0;gb?a.push(b):2048>b?a.push(192|b>>6,128|b&63):55296>b||57344<=b?a.push(224|b>>12,128|b>>6&63,128|b&63):(e++,b=65536+((b&1023)<<10|c.charCodeAt(e)&1023),a.push(240|b>>18,128|b>>12&63,128|b>>6&63,128|b&63))}return a};var A={L:1,M:0,Q:3,H:2},y=function(){function c(b){for(var a=0;0!=b;)a+=1,b>>>=1;return a}var a=[[],[6,18], +[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154], +[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],e={w:function(b){for(var a=b<<10;0<=c(a)-c(1335);)a^=1335<a||40a?8:16},D:function(b){for(var a=b.h(),c=0, +d=0;d=p;p+=1)if(!(0>d+p||a<=d+p))for(var q=-1;1>=q;q+=1)0>g+q||a<=g+q||(0!=p||0!=q)&&t==b.a(d+p,g+q)&&(e+=1);5e;e+=1)c[e]=1<e;e+=1)c[e]=c[e-4]^c[e-5]^c[e-6]^c[e-8];for(e=0;255>e;e+=1)a[c[e]]=e;return{g:function(b){if(1>b)throw Error("glog("+b+")");return a[b]},i:function(b){for(;0>b;)b+=255;for(;256<=b;)b-=255;return c[b]}}}(),t=function(){function c(b,c){switch(c){case A.L:return a[4* +(b-1)];case A.M:return a[4*(b-1)+1];case A.Q:return a[4*(b-1)+2];case A.H:return a[4*(b-1)+3]}}var a=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36, +2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73, +45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4, +151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117], +[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48], +[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],e={I:function(b,a){var e=c(b,a);if("undefined"== +typeof e)throw Error("bad rs block @ typeNumber:"+b+"/errorCorrectLevel:"+a);b=e.length/3;a=[];for(var d=0;d +

+

Sats

+
+
+ +
+ +
+
+ `; + static paymentConfirmationTemplate = `

Payment sent!

`; + + constructor(options) { + this.script = document.getElementById('lnme-script'); + if (options.baseURL) { + this.baseURL = options.baseURL; + } else if (this.script.dataset.lnmeBaseUrl) { + this.baseURL = this.script.dataset.lnmeBaseUrl; + } else { + let url = new URL(this.script.src); + this.baseURL = `${url.protocol}//${url.host}`; + } + this.value = parseInt(options.value || 0); + this.memo = options.memo || ''; + this.target = options.target; + this.loadStylesheet(); // load it early that styles are ready when the popup is opened + } + + loadStylesheet() { + if (document.getElementById('lnme-style')) { return; } + // get the CSS file from the same source as the JS widget file + let source = this.script.src.replace(/\.js$/, ".css"); + console.log(source); + let head = document.getElementsByTagName('head')[0]; + let css = document.createElement('link'); + css.id = "lnme-style"; + css.rel = "stylesheet"; + css.type = "text/css"; + css.href = source + head.appendChild(css); + } + + watchPayment() { + if (this.paymentWatcher) { window.clearInterval(this.paymentWatcher) } + + return new Promise((resolve, reject) => { + this.paymentWatcher = window.setInterval(() => { + this._fetch(`${this.baseURL}/v1/invoice/${this.invoice.payment_hash}`) + .then((invoice) => { + if (invoice.settled) { + this.invoice.settled = true; + this.stopWatchingPayment(); + resolve(this.invoice); + } + }); + }, 2000); + }); + } + + stopWatchingPayment() { + window.clearInterval(this.paymentWatcher); + this.paymentWatcher = null; + } + + payWithWebln() { + if (!webln.isEnabled) { + webln.enable().then((weblnResponse) => { + return webln.sendPayment({ paymentRequest: this.invoice.payment_request }) + }).catch((e) => { + return this.showPaymentRequest(); + }) + } else { + return webln.sendPayment({ paymentRequest: this.invoice.payment_request }) + } + } + + populatePaymentRequest() { + document.querySelectorAll('.lnme-memo').forEach(e => { + e.innerHTML = this.memo; + }); + document.querySelectorAll('.lnme-value').forEach(e => { + e.innerHTML = this.value; + }); + document.querySelectorAll('.lnme-payment-request').forEach(e => { + e.innerHTML = this.invoice.payment_request; + }); + document.querySelectorAll('.lnme-link').forEach(e => { + e.setAttribute('href', `lightning:${this.invoice.payment_request}`); + }); + QrCreator.render({ text: this.invoice.payment_request, size: 128}, this.target.querySelector('.lnme-qrcode')); + this.target.querySelectorAll('.lnme-copy').forEach(element => { + element.addEventListener('click', (e) => { + navigator.clipboard.writeText(this.invoice.payment_request).then(() => { + alert('Copied to clipboad'); + }); + }); + }); + } + + showPaymentRequest() { + this.render(LnMe.paymentRequestTemplate); + this.populatePaymentRequest() + return Promise.resolve(); // be compatible to payWithWebln() + } + + addInvoice() { + let args = { + method: 'POST', + mode: 'cors', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ memo: this.memo, value: this.value }) + }; + return this._fetch( + `${this.baseURL}/v1/invoices`, + args + ).then((invoice) => { + this.invoice = invoice; + return invoice; + }); + } + + requestPayment() { + return this.addInvoice().then((invoice) => { + if (typeof webln !== 'undefined') { + return this.payWithWebln(); + } else { + return this.showPaymentRequest(); + } + }); + } + + request() { + return this.requestPayment().then(() => { + this.watchPayment().then((invoice) => { + this.thanks(); + }); + }); + } + + _fetch(url, args) { + return fetch(url, args).then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error(response); + } + }); + } + + closePopup() { + if (this.popup) { + this.popup.close(); + this.popup = null; + } + } + + render(content) { + this.closePopup(); + this.popup = new jPopup({ + content: content, + shouldSetHash: false + }); + this.target = document.querySelector('.jPopup .content').firstElementChild; + } + + thanks() { + this.target.innerHTML = LnMe.paymentConfirmationTemplate; + } +} diff --git a/files/root/index.html b/files/root/index.html new file mode 100644 index 0000000..923d22b --- /dev/null +++ b/files/root/index.html @@ -0,0 +1,142 @@ + + + + + Send me some Sats + + + + +
+
+

+ Send me
+ Sats +
+ for +
+ +

+ + +
+
+ + + + + diff --git a/invoices_proxy.go b/invoices_proxy.go index f78745b..92f562d 100644 --- a/invoices_proxy.go +++ b/invoices_proxy.go @@ -2,11 +2,12 @@ package main import ( "flag" + "github.com/GeertJohan/go.rice" "github.com/bumi/lntip/ln" - "github.com/labstack/echo" - "github.com/labstack/echo/middleware" "github.com/didip/tollbooth" "github.com/didip/tollbooth/limiter" + "github.com/labstack/echo" + "github.com/labstack/echo/middleware" "log" "net/http" "os" @@ -16,7 +17,7 @@ import ( func LimitMiddleware(lmt *limiter.Limiter) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return echo.HandlerFunc(func(c echo.Context) error { - httpError := tollbooth.LimitByRequest(lmt, c.Response(), c.Request()) + httpError := tollbooth.LimitByRequest(lmt, c.Response(), c.Request()) if httpError != nil { return c.String(httpError.StatusCode, httpError.Message) } @@ -37,16 +38,27 @@ func main() { certFile := flag.String("cert", "~/.lnd/tls.cert", "Path to the lnd tls.cert file") macaroonFile := flag.String("macaroon", "~/.lnd/data/chain/bitcoin/mainnet/invoice.macaroon", "Path to the lnd macaroon file") bind := flag.String("bind", ":1323", "Host and port to bind on") - staticPath := flag.String("static-path", "", "Path to a static assets directory. Blank to disable serving static files") + staticPath := flag.String("static-path", "", "Path to a static assets directory. Blank to not serve any static files") + disableHTML := flag.Bool("disable-html", false, "Disable HTML page") disableCors := flag.Bool("disable-cors", false, "Disable CORS headers") - requestLimit := flag.Float64("request-limit", 10, "Request limit per second") + requestLimit := flag.Float64("request-limit", 5, "Request limit per second") flag.Parse() e := echo.New() if *staticPath != "" { - e.Static("/static", *staticPath) + e.Static("/", *staticPath) + } else if !*disableHTML { + rootBox := rice.MustFindBox("files/root") + indexPage, err := rootBox.String("index.html") + if err == nil { + stdOutLogger.Print("Running page") + e.GET("/", func(c echo.Context) error { + return c.HTML(200, indexPage) + }) + } } + if !*disableCors { e.Use(middleware.CORS()) } @@ -57,6 +69,10 @@ func main() { e.Use(LimitMiddleware(limiter)) } + // Embed static files and serve those on /lnme (e.g. /lnme/lnme.js) + assetHandler := http.FileServer(rice.MustFindBox("files/assets").HTTPBox()) + e.GET("/lnme/*", echo.WrapHandler(http.StripPrefix("/lnme/", assetHandler))) + stdOutLogger.Printf("Connection to %s using macaroon %s and cert %s", *address, *macaroonFile, *certFile) lndOptions := ln.LNDoptions{ Address: *address,