-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebLn Implementaion to Quick-pay #19
base: version6
Are you sure you want to change the base?
WebLn Implementaion to Quick-pay #19
Conversation
…e branch 'webln' of https://github.com/SanjaySinghRajpoot/RTL-Quickpay into webln
Tiny updates
@coderabbitai review |
WalkthroughThe recent updates involve integrating Lightning Network capabilities into a web service, enhancing interactivity with a node through new connectors, interfaces, and provider classes. Error handling and message formatting have been refined across various modules, and scripts for enabling inpage interaction with a browser extension have been added. The changes aim to streamline payment processes, node interactions, and improve the user experience with more consistent and robust error messaging. Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 5
Configuration used: CodeRabbit UI
Files ignored due to path filters (15)
dist/assets/themes/day/indigo.css
is excluded by:!dist/**
dist/assets/themes/day/pink.css
is excluded by:!dist/**
dist/assets/themes/day/purple.css
is excluded by:!dist/**
dist/assets/themes/day/teal.css
is excluded by:!dist/**
dist/assets/themes/day/yellow.css
is excluded by:!dist/**
dist/assets/themes/night/indigo.css
is excluded by:!dist/**
dist/assets/themes/night/pink.css
is excluded by:!dist/**
dist/assets/themes/night/purple.css
is excluded by:!dist/**
dist/assets/themes/night/teal.css
is excluded by:!dist/**
dist/assets/themes/night/yellow.css
is excluded by:!dist/**
dist/manifest.json
is excluded by:!dist/**, !**/*.json
dist/pages/payment.js
is excluded by:!dist/**
dist/scripts/content.js
is excluded by:!dist/**
packages/RTL-Quickpay-v0.0.6.zip
is excluded by:!**/*.zip
src/manifest.json
is excluded by:!**/*.json
Files selected for processing (11)
- src/actions/webln_action.js (1 hunks)
- src/connectors/cln.js (1 hunks)
- src/connectors/connectors.interface.js (1 hunks)
- src/pages/error.js (1 hunks)
- src/pages/payment.js (3 hunks)
- src/scripts/background.js (2 hunks)
- src/scripts/content.js (1 hunks)
- src/scripts/injectScript.js (1 hunks)
- src/shared/constants.js (1 hunks)
- src/shared/utils.js (2 hunks)
- src/webln/webln.js (1 hunks)
Additional comments: 12
src/connectors/connectors.interface.js (1)
- 1-9: The interface definitions for
WebLNNode
andGetInfoResponse
are clear and concise. They establish a contract for the shape of data related to Lightning Network nodes, which is essential for type safety and code maintainability.src/pages/error.js (2)
- 25-32: The error handling logic correctly checks the type of
self.errorData.error
and converts it to a string if necessary. It then updates the UI elements with the error message and title. This is a good use of defensive programming to ensure the error data is in the expected format before displaying it to the user.- 37-44: The click event handler for the back button is set up correctly to load the previous module when the button is clicked. This provides a clear navigation path for the user to return to the previous state after encountering an error.
src/scripts/content.js (1)
- 1-68: The content script sets up event listeners for user interactions and sends messages to the background script as expected. The use of
window.webln
to provide WebLN functionality to the page is a good practice, as it encapsulates the WebLN provider within the window object, making it accessible to the page scripts.src/actions/webln_action.js (3)
- 4-16: The
getInfo
function correctly retrieves connector information and formats the response to match the expectedWebLNNode
interface. This ensures consistency in the data structure used throughout the application.- 19-44: The
makeInvoiceWithPrompt
function provides a good user experience by allowing the invoice amount and memo to be editable based on the presence of the respective arguments. The error handling is also appropriate, returning an error object if an exception occurs.- 60-67: The
signMessageOrPrompt
function checks if the message to sign is a string and returns an error if not. This is a good practice to validate input before processing.src/shared/constants.js (1)
- 70-70: The addition of the
REQUEST_GETINFO
global variable is consistent with the rest of the constants defined in the file. It's good practice to keep such constants centralized for easier management and updates.src/shared/utils.js (1)
- 21-73: The
getOriginData
function and its helper functionsgetDomain
,getName
, andgetIcon
are well-implemented to extract relevant data from the current web page. They use appropriate DOM methods and provide fallbacks where necessary.src/connectors/cln.js (1)
- 4-129: The
Cln
class provides methods for interacting with the Core Lightning node. Therequest
method is well-implemented with proper error handling and response parsing. The use offetch
with appropriate headers and body formatting is correct. Ensure that sensitive data like macaroons are handled securely.src/pages/payment.js (2)
- 18-20: The
Payment
module correctly initializes aWebLNProvider
instance. This is a crucial step for integrating WebLN functionality into the payment process.- 222-225: The error handling for an invalid invoice ID is updated to display a specific error message. This improves user feedback and helps in diagnosing input errors.
var browser = require('webextension-polyfill'); | ||
|
||
// load the inpage script | ||
// only an inpage script gets access to the document | ||
// and the document can interact with the extension through the inpage script | ||
export default function injectScript() { | ||
try { | ||
if (!document) throw new Error("No document"); | ||
const container = document.head || document.documentElement; | ||
if (!container) throw new Error("No container element"); | ||
const scriptEl = document.createElement("script"); | ||
scriptEl.setAttribute("async", "false"); | ||
scriptEl.setAttribute("type", "text/javascript"); | ||
scriptEl.setAttribute( | ||
"src", | ||
browser.extension.getURL("js/inpageScript.bundle.js") | ||
); | ||
container.appendChild(scriptEl); | ||
} catch (err) { | ||
console.error("WebLN injection failed", err); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The injectScript
function correctly checks for the presence of document
and the container element before creating and appending the script element. It also handles errors appropriately by logging them to the console. However, consider removing the async
attribute setting as it is not necessary when setting the attribute to "false" and could be misleading.
- scriptEl.setAttribute("async", "false");
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
var browser = require('webextension-polyfill'); | |
// load the inpage script | |
// only an inpage script gets access to the document | |
// and the document can interact with the extension through the inpage script | |
export default function injectScript() { | |
try { | |
if (!document) throw new Error("No document"); | |
const container = document.head || document.documentElement; | |
if (!container) throw new Error("No container element"); | |
const scriptEl = document.createElement("script"); | |
scriptEl.setAttribute("async", "false"); | |
scriptEl.setAttribute("type", "text/javascript"); | |
scriptEl.setAttribute( | |
"src", | |
browser.extension.getURL("js/inpageScript.bundle.js") | |
); | |
container.appendChild(scriptEl); | |
} catch (err) { | |
console.error("WebLN injection failed", err); | |
} | |
} | |
var browser = require('webextension-polyfill'); | |
// load the inpage script | |
// only an inpage script gets access to the document | |
// and the document can interact with the extension through the inpage script | |
export default function injectScript() { | |
try { | |
if (!document) throw new Error("No document"); | |
const container = document.head || document.documentElement; | |
if (!container) throw new Error("No container element"); | |
const scriptEl = document.createElement("script"); | |
scriptEl.setAttribute("type", "text/javascript"); | |
scriptEl.setAttribute( | |
"src", | |
browser.extension.getURL("js/inpageScript.bundle.js") | |
); | |
container.appendChild(scriptEl); | |
} catch (err) { | |
console.error("WebLN injection failed", err); | |
} | |
} |
async function payWithPrompt(message) { | ||
try { | ||
const response = await utils.openPrompt(Object.assign(Object.assign({}, message), { action: "confirmPayment" })); | ||
return response; | ||
} | ||
catch (e) { | ||
console.error("Payment cancelled", e); | ||
if (e instanceof Error) { | ||
return { error: e.message }; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The payWithPrompt
function is designed to handle user confirmation for payments. The error handling could be improved by providing a more detailed error message to the user, rather than just logging it to the console.
- console.error("Payment cancelled", e);
+ return { error: "Payment cancelled: " + (e instanceof Error ? e.message : e) };
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
async function payWithPrompt(message) { | |
try { | |
const response = await utils.openPrompt(Object.assign(Object.assign({}, message), { action: "confirmPayment" })); | |
return response; | |
} | |
catch (e) { | |
console.error("Payment cancelled", e); | |
if (e instanceof Error) { | |
return { error: e.message }; | |
} | |
} | |
async function payWithPrompt(message) { | |
try { | |
const response = await utils.openPrompt(Object.assign(Object.assign({}, message), { action: "confirmPayment" })); | |
return response; | |
} | |
catch (e) { | |
return { error: "Payment cancelled: " + (e instanceof Error ? e.message : e) }; | |
if (e instanceof Error) { | |
return { error: e.message }; | |
} | |
} | |
} |
export default class WebLNProvider { | ||
constructor() { | ||
this.enabled = false; | ||
this.isEnabled = false; | ||
this.executing = false; | ||
} | ||
enable() { | ||
if (this.enabled) { | ||
return Promise.resolve({ enabled: true }); | ||
} | ||
return this.execute("enable").then((result) => { | ||
if (typeof result.enabled === "boolean") { | ||
this.enabled = result.enabled; | ||
this.isEnabled = result.enabled; | ||
} | ||
return result; | ||
}); | ||
} | ||
getInfo() { | ||
if (!this.enabled) { | ||
throw new Error("Provider must be enabled before calling getInfo"); | ||
} | ||
return this.execute("getInfo"); | ||
} | ||
|
||
// NOTE: new call `action`s must be specified also in the content script | ||
execute(action, args) { | ||
return new Promise((resolve, reject) => { | ||
// post the request to the content script. from there it gets passed to the background script and back | ||
// in page script can not directly connect to the background script | ||
window.postMessage({ | ||
application: "RTL", | ||
prompt: true, | ||
action: `${action}`, | ||
args, | ||
}, "*" // TODO use origin | ||
); | ||
function handleWindowMessage(messageEvent) { | ||
// check if it is a relevant message | ||
// there are some other events happening | ||
if (!messageEvent.data || | ||
!messageEvent.data.response || | ||
messageEvent.data.application !== "RTL") { | ||
return; | ||
} | ||
if (messageEvent.data.data.error) { | ||
reject(new Error(messageEvent.data.data.error)); | ||
} | ||
else { | ||
// 1. data: the message data | ||
// 2. data: the data passed as data to the message | ||
// 3. data: the actual response data | ||
resolve(messageEvent.data.data.data); | ||
} | ||
// For some reason must happen only at the end of this function | ||
window.removeEventListener("message", handleWindowMessage); | ||
} | ||
window.addEventListener("message", handleWindowMessage); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The WebLNProvider
class is well-structured, with methods to enable the provider, retrieve information, and execute actions. The execute
method's use of window messaging is appropriate for communication between the content script and the background script. However, consider validating the origin when posting and receiving messages for added security.
- }, "*" // TODO use origin
+ }, window.location.origin)
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
export default class WebLNProvider { | |
constructor() { | |
this.enabled = false; | |
this.isEnabled = false; | |
this.executing = false; | |
} | |
enable() { | |
if (this.enabled) { | |
return Promise.resolve({ enabled: true }); | |
} | |
return this.execute("enable").then((result) => { | |
if (typeof result.enabled === "boolean") { | |
this.enabled = result.enabled; | |
this.isEnabled = result.enabled; | |
} | |
return result; | |
}); | |
} | |
getInfo() { | |
if (!this.enabled) { | |
throw new Error("Provider must be enabled before calling getInfo"); | |
} | |
return this.execute("getInfo"); | |
} | |
// NOTE: new call `action`s must be specified also in the content script | |
execute(action, args) { | |
return new Promise((resolve, reject) => { | |
// post the request to the content script. from there it gets passed to the background script and back | |
// in page script can not directly connect to the background script | |
window.postMessage({ | |
application: "RTL", | |
prompt: true, | |
action: `${action}`, | |
args, | |
}, "*" // TODO use origin | |
); | |
function handleWindowMessage(messageEvent) { | |
// check if it is a relevant message | |
// there are some other events happening | |
if (!messageEvent.data || | |
!messageEvent.data.response || | |
messageEvent.data.application !== "RTL") { | |
return; | |
} | |
if (messageEvent.data.data.error) { | |
reject(new Error(messageEvent.data.data.error)); | |
} | |
else { | |
// 1. data: the message data | |
// 2. data: the data passed as data to the message | |
// 3. data: the actual response data | |
resolve(messageEvent.data.data.data); | |
} | |
// For some reason must happen only at the end of this function | |
window.removeEventListener("message", handleWindowMessage); | |
} | |
window.addEventListener("message", handleWindowMessage); | |
}); | |
} | |
export default class WebLNProvider { | |
constructor() { | |
this.enabled = false; | |
this.isEnabled = false; | |
this.executing = false; | |
} | |
enable() { | |
if (this.enabled) { | |
return Promise.resolve({ enabled: true }); | |
} | |
return this.execute("enable").then((result) => { | |
if (typeof result.enabled === "boolean") { | |
this.enabled = result.enabled; | |
this.isEnabled = result.enabled; | |
} | |
return result; | |
}); | |
} | |
getInfo() { | |
if (!this.enabled) { | |
throw new Error("Provider must be enabled before calling getInfo"); | |
} | |
return this.execute("getInfo"); | |
} | |
// NOTE: new call `action`s must be specified also in the content script | |
execute(action, args) { | |
return new Promise((resolve, reject) => { | |
// post the request to the content script. from there it gets passed to the background script and back | |
// in page script can not directly connect to the background script | |
window.postMessage({ | |
application: "RTL", | |
prompt: true, | |
action: `${action}`, | |
args, | |
}, window.location.origin) | |
function handleWindowMessage(messageEvent) { | |
// check if it is a relevant message | |
// there are some other events happening | |
if (!messageEvent.data || | |
!messageEvent.data.response || | |
messageEvent.data.application !== "RTL") { | |
return; | |
} | |
if (messageEvent.data.data.error) { | |
reject(new Error(messageEvent.data.data.error)); | |
} | |
else { | |
// 1. data: the message data | |
// 2. data: the data passed as data to the message | |
// 3. data: the actual response data | |
resolve(messageEvent.data.data.data); | |
} | |
// For some reason must happen only at the end of this function | |
window.removeEventListener("message", handleWindowMessage); | |
} | |
window.addEventListener("message", handleWindowMessage); | |
}); | |
} |
const utils = { | ||
call: (action, args, overwrites) => { | ||
return browser.runtime | ||
.sendMessage(Object.assign({ application: "RTL", prompt: true, action: action, args: args, origin: { internal: true } }, overwrites)) | ||
.then((response) => { | ||
if (response.error) { | ||
toast.error(response.error); | ||
throw new Error(response.error); | ||
} | ||
return response.data; | ||
}); | ||
}, | ||
base64ToHex: (str) => { | ||
const hex = []; | ||
for (let i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")); i < bin.length; ++i) { | ||
let tmp = bin.charCodeAt(i).toString(16); | ||
if (tmp.length === 1) | ||
tmp = "0" + tmp; | ||
hex[hex.length] = tmp; | ||
} | ||
return hex.join(""); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The utils
object contains methods for making API calls and converting base64 to hex. The call
method's error handling could be improved by providing more context in the error message.
- throw new Error(response.error);
+ throw new Error("API call failed: " + response.error);
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const utils = { | |
call: (action, args, overwrites) => { | |
return browser.runtime | |
.sendMessage(Object.assign({ application: "RTL", prompt: true, action: action, args: args, origin: { internal: true } }, overwrites)) | |
.then((response) => { | |
if (response.error) { | |
toast.error(response.error); | |
throw new Error(response.error); | |
} | |
return response.data; | |
}); | |
}, | |
base64ToHex: (str) => { | |
const hex = []; | |
for (let i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")); i < bin.length; ++i) { | |
let tmp = bin.charCodeAt(i).toString(16); | |
if (tmp.length === 1) | |
tmp = "0" + tmp; | |
hex[hex.length] = tmp; | |
} | |
return hex.join(""); | |
}, | |
const utils = { | |
call: (action, args, overwrites) => { | |
return browser.runtime | |
.sendMessage(Object.assign({ application: "RTL", prompt: true, action: action, args: args, origin: { internal: true } }, overwrites)) | |
.then((response) => { | |
if (response.error) { | |
toast.error(response.error); | |
throw new Error("API call failed: " + response.error); | |
} | |
return response.data; | |
}); | |
}, | |
base64ToHex: (str) => { | |
const hex = []; | |
for (let i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")); i < bin.length; ++i) { | |
let tmp = bin.charCodeAt(i).toString(16); | |
if (tmp.length === 1) | |
tmp = "0" + tmp; | |
hex[hex.length] = tmp; | |
} | |
return hex.join(""); | |
}, |
const weblnCalls = ["getInfo"]; | ||
|
||
// calls that can be executed when webln is not enabled for the current content page | ||
const disabledCalls = ["enable"]; | ||
|
||
let isEnabled = false; // store if webln is enabled for this content page | ||
let callActive = false; // store if a webln is currently active. Used to prevent multiple calls in parallel | ||
|
||
async function init() { | ||
|
||
injectScript(); // injects the webln object | ||
|
||
// message listener to listen to inpage webln calls | ||
// those calls get passed on to the background script | ||
// (the inpage script can not do that directly, but only the inpage script can make webln available to the page) | ||
window.addEventListener("message", (ev) => { | ||
// Only accept messages from the current window | ||
if (ev.source !== window) { | ||
return; | ||
} | ||
if (ev.data && ev.data.application === "RTL" && !ev.data.response) { | ||
// if a call is active we ignore the request | ||
if (callActive) { | ||
console.error("WebLN call already executing"); | ||
return; | ||
} | ||
// limit the calls that can be made from webln | ||
// only listed calls can be executed | ||
// if not enabled only enable can be called. | ||
const availableCalls = isEnabled ? weblnCalls : disabledCalls; | ||
if (!availableCalls.includes(ev.data.action)) { | ||
console.error("Function not available. Is the provider enabled?"); | ||
return; | ||
} | ||
|
||
const messageWithOrigin = { | ||
action: `webln/${ev.data.action}`, // every webln call must be scoped under `webln/` we do this to indicate that those actions are callable from the websites | ||
args: ev.data.args, | ||
application: "RTL", | ||
public: true, // indicate that this is a public call from the content script | ||
prompt: true, | ||
origin: getOriginData(), | ||
}; | ||
const replyFunction = (response) => { | ||
callActive = false; // reset call is active | ||
// if it is the enable call we store if webln is enabled for this content script | ||
if (ev.data.action === "enable") { | ||
isEnabled = response.data?.enabled; | ||
} | ||
window.postMessage( | ||
{ | ||
application: "RTL", | ||
response: true, | ||
data: response, | ||
}, | ||
"*" // TODO use origin | ||
); | ||
}; | ||
callActive = true; | ||
return browser.runtime | ||
.sendMessage(messageWithOrigin) | ||
.then(replyFunction) | ||
.catch(replyFunction); | ||
} | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The background.js
file sets up the necessary infrastructure for handling WebLN calls. The init
function and the message listener are correctly implemented to handle and process these calls. The use of isEnabled
and callActive
flags to manage the state is a good practice. Ensure that the TODO to use the origin in window.postMessage
is addressed for security reasons.
- }, "*" // TODO use origin
+ }, window.location.origin)
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
const weblnCalls = ["getInfo"]; | |
// calls that can be executed when webln is not enabled for the current content page | |
const disabledCalls = ["enable"]; | |
let isEnabled = false; // store if webln is enabled for this content page | |
let callActive = false; // store if a webln is currently active. Used to prevent multiple calls in parallel | |
async function init() { | |
injectScript(); // injects the webln object | |
// message listener to listen to inpage webln calls | |
// those calls get passed on to the background script | |
// (the inpage script can not do that directly, but only the inpage script can make webln available to the page) | |
window.addEventListener("message", (ev) => { | |
// Only accept messages from the current window | |
if (ev.source !== window) { | |
return; | |
} | |
if (ev.data && ev.data.application === "RTL" && !ev.data.response) { | |
// if a call is active we ignore the request | |
if (callActive) { | |
console.error("WebLN call already executing"); | |
return; | |
} | |
// limit the calls that can be made from webln | |
// only listed calls can be executed | |
// if not enabled only enable can be called. | |
const availableCalls = isEnabled ? weblnCalls : disabledCalls; | |
if (!availableCalls.includes(ev.data.action)) { | |
console.error("Function not available. Is the provider enabled?"); | |
return; | |
} | |
const messageWithOrigin = { | |
action: `webln/${ev.data.action}`, // every webln call must be scoped under `webln/` we do this to indicate that those actions are callable from the websites | |
args: ev.data.args, | |
application: "RTL", | |
public: true, // indicate that this is a public call from the content script | |
prompt: true, | |
origin: getOriginData(), | |
}; | |
const replyFunction = (response) => { | |
callActive = false; // reset call is active | |
// if it is the enable call we store if webln is enabled for this content script | |
if (ev.data.action === "enable") { | |
isEnabled = response.data?.enabled; | |
} | |
window.postMessage( | |
{ | |
application: "RTL", | |
response: true, | |
data: response, | |
}, | |
"*" // TODO use origin | |
); | |
}; | |
callActive = true; | |
return browser.runtime | |
.sendMessage(messageWithOrigin) | |
.then(replyFunction) | |
.catch(replyFunction); | |
} | |
}); | |
} | |
const weblnCalls = ["getInfo"]; | |
// calls that can be executed when webln is not enabled for the current content page | |
const disabledCalls = ["enable"]; | |
let isEnabled = false; // store if webln is enabled for this content page | |
let callActive = false; // store if a webln is currently active. Used to prevent multiple calls in parallel | |
async function init() { | |
injectScript(); // injects the webln object | |
// message listener to listen to inpage webln calls | |
// those calls get passed on to the background script | |
// (the inpage script can not do that directly, but only the inpage script can make webln available to the page) | |
window.addEventListener("message", (ev) => { | |
// Only accept messages from the current window | |
if (ev.source !== window) { | |
return; | |
} | |
if (ev.data && ev.data.application === "RTL" && !ev.data.response) { | |
// if a call is active we ignore the request | |
if (callActive) { | |
console.error("WebLN call already executing"); | |
return; | |
} | |
// limit the calls that can be made from webln | |
// only listed calls can be executed | |
// if not enabled only enable can be called. | |
const availableCalls = isEnabled ? weblnCalls : disabledCalls; | |
if (!availableCalls.includes(ev.data.action)) { | |
console.error("Function not available. Is the provider enabled?"); | |
return; | |
} | |
const messageWithOrigin = { | |
action: `webln/${ev.data.action}`, // every webln call must be scoped under `webln/` we do this to indicate that those actions are callable from the websites | |
args: ev.data.args, | |
application: "RTL", | |
public: true, // indicate that this is a public call from the content script | |
prompt: true, | |
origin: getOriginData(), | |
}; | |
const replyFunction = (response) => { | |
callActive = false; // reset call is active | |
// if it is the enable call we store if webln is enabled for this content script | |
if (ev.data.action === "enable") { | |
isEnabled = response.data?.enabled; | |
} | |
window.postMessage( | |
{ | |
application: "RTL", | |
response: true, | |
data: response, | |
}, | |
window.location.origin) | |
}; | |
callActive = true; | |
return browser.runtime | |
.sendMessage(messageWithOrigin) | |
.then(replyFunction) | |
.catch(replyFunction); | |
} | |
}); | |
} |
Description
WebLn library added to the Quick-Pay browser extension. With the help of this, all the WebLn features will be implemented inside the
content.js
file and a new webln script will be created. It provides a programmatic, permissioned interface for letting applications ask users to send payments, generates invoices to receive payments, and much more. This documentation covers both how to use WebLN in your Lightning-driven applications, but also how to implement a provider.Changes
Thank You
Summary by CodeRabbit
New Features
WebLNProvider
for initiating web Lightning Network interactions.Bug Fixes
Style
Documentation
Chores
REQUEST_GETINFO
.