@getalby/lightning-tools
Version:
Collection of helpful building blocks and tools to develop Bitcoin Lightning web apps
85 lines (82 loc) • 2.73 kB
JavaScript
class MemoryStorage {
constructor(initial) {
this.storage = initial || {};
}
getItem(key) {
return this.storage[key];
}
setItem(key, value) {
this.storage[key] = value;
}
}
class NoStorage {
constructor(initial) { }
getItem(key) {
return null;
}
setItem(key, value) { }
}
const parseL402 = (input) => {
// Remove the L402 and LSAT identifiers
const string = input.replace("L402", "").replace("LSAT", "").trim();
// Initialize an object to store the key-value pairs
const keyValuePairs = {};
// Regular expression to match key and (quoted or unquoted) value
const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,]*))/g;
let match;
// Use regex to find all key-value pairs
while ((match = regex.exec(string)) !== null) {
// Key is always match[1]
// Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)
keyValuePairs[match[1]] = match[3] || match[4] || match[5];
}
return keyValuePairs;
};
const memoryStorage = new MemoryStorage();
const HEADER_KEY = "L402"; // we have to update this to L402 at some point
const fetchWithL402 = async (url, fetchArgs, options) => {
if (!options) {
options = {};
}
const headerKey = options.headerKey || HEADER_KEY;
const webln = options.webln || globalThis.webln;
if (!webln) {
throw new Error("WebLN is missing");
}
const store = options.store || memoryStorage;
if (!fetchArgs) {
fetchArgs = {};
}
fetchArgs.cache = "no-store";
fetchArgs.mode = "cors";
if (!fetchArgs.headers) {
fetchArgs.headers = {};
}
const cachedL402Data = store.getItem(url);
if (cachedL402Data) {
const data = JSON.parse(cachedL402Data);
fetchArgs.headers["Authorization"] =
`${headerKey} ${data.token}:${data.preimage}`;
return await fetch(url, fetchArgs);
}
fetchArgs.headers["Accept-Authenticate"] = headerKey;
const initResp = await fetch(url, fetchArgs);
const header = initResp.headers.get("www-authenticate");
if (!header) {
return initResp;
}
const details = parseL402(header);
const token = details.token || details.macaroon;
const inv = details.invoice;
await webln.enable();
const invResp = await webln.sendPayment(inv);
store.setItem(url, JSON.stringify({
token: token,
preimage: invResp.preimage,
}));
fetchArgs.headers["Authorization"] =
`${headerKey} ${token}:${invResp.preimage}`;
return await fetch(url, fetchArgs);
};
export { MemoryStorage, NoStorage, fetchWithL402, parseL402 };
//# sourceMappingURL=l402.js.map