@getalby/lightning-tools 6.0.0 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -7
- package/dist/cjs/fiat.cjs +21 -0
- package/dist/cjs/fiat.cjs.map +1 -1
- package/dist/cjs/index.cjs +31 -6
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/l402.cjs +10 -6
- package/dist/cjs/l402.cjs.map +1 -1
- package/dist/esm/fiat.js +21 -1
- package/dist/esm/fiat.js.map +1 -1
- package/dist/esm/index.js +30 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l402.js +10 -7
- package/dist/esm/l402.js.map +1 -1
- package/dist/lightning-tools.umd.js +2 -2
- package/dist/lightning-tools.umd.js.map +1 -1
- package/dist/types/fiat.d.ts +9 -1
- package/dist/types/index.d.ts +20 -3
- package/dist/types/l402.d.ts +12 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
An npm package that provides useful and common tools and helpers to build lightning web applications.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Before you start coding, look at example scenarios in our **[Developer Sandbox](https://sandbox.albylabs.com/)**
|
|
10
|
+
|
|
11
|
+
## 🤖 🚀 ⚡ For Developers using Agents / LLMs / Vibe Coding
|
|
12
|
+
|
|
13
|
+
Skip the rest of this README and use the [Alby Bitcoin Payments Agent Skill](https://github.com/getAlby/alby-agent-skill) instead. It will handle the rest!
|
|
14
|
+
|
|
15
|
+
## Manual Installation
|
|
10
16
|
|
|
11
17
|
```
|
|
12
18
|
npm install @getalby/lightning-tools
|
|
@@ -175,7 +181,7 @@ This library includes a `fetchWithL402` function to consume L402 protected resou
|
|
|
175
181
|
- url: the L402 protected URL
|
|
176
182
|
- fetchArgs: arguments are passed to the underlying `fetch()` function used to do the HTTP request
|
|
177
183
|
- options:
|
|
178
|
-
-
|
|
184
|
+
- wallet: any object that implements `sendPayment(paymentRequest)` and returns `{ preimage }`. Used to pay the L402 invoice.
|
|
179
185
|
- store: a key/value store object to persiste the l402 for each URL. The store must implement a `getItem()`/`setItem()` function as the browser's localStorage. By default a memory storage is used.
|
|
180
186
|
- headerKey: defaults to L402 but if you need to consume an old LSAT API set this to LSAT
|
|
181
187
|
|
|
@@ -184,12 +190,12 @@ This library includes a `fetchWithL402` function to consume L402 protected resou
|
|
|
184
190
|
```js
|
|
185
191
|
import { fetchWithL402 } from "@getalby/lightning-tools/l402";
|
|
186
192
|
|
|
187
|
-
//
|
|
193
|
+
// pass a wallet that implements sendPayment()
|
|
188
194
|
// the tokens/preimage data will be stored in the browser's localStorage and used for any following request
|
|
189
195
|
await fetchWithL402(
|
|
190
196
|
"https://lsat-weather-api.getalby.repl.co/kigali",
|
|
191
197
|
{},
|
|
192
|
-
{ store: window.localStorage },
|
|
198
|
+
{ wallet: myWallet, store: window.localStorage },
|
|
193
199
|
)
|
|
194
200
|
.then((res) => res.json())
|
|
195
201
|
.then(console.log);
|
|
@@ -199,16 +205,16 @@ await fetchWithL402(
|
|
|
199
205
|
import { fetchWithL402 } from "@getalby/lightning-tools/l402";
|
|
200
206
|
import { NostrWebLNProvider } from "@getalby/sdk";
|
|
201
207
|
|
|
202
|
-
// use a NWC
|
|
208
|
+
// use a NWC provider as the wallet to do the payments
|
|
203
209
|
const nwc = new NostrWebLNProvider({
|
|
204
210
|
nostrWalletConnectUrl: loadNWCUrl(),
|
|
205
211
|
});
|
|
206
212
|
|
|
207
|
-
// this will fetch the resource and pay the invoice
|
|
213
|
+
// this will fetch the resource and pay the invoice using the NWC wallet
|
|
208
214
|
await fetchWithL402(
|
|
209
215
|
"https://lsat-weather-api.getalby.repl.co/kigali",
|
|
210
216
|
{},
|
|
211
|
-
{
|
|
217
|
+
{ wallet: nwc },
|
|
212
218
|
)
|
|
213
219
|
.then((res) => res.json())
|
|
214
220
|
.then(console.log);
|
|
@@ -242,6 +248,10 @@ const { paymentHash, satoshi, description, createdDate, expiryDate } = invoice;
|
|
|
242
248
|
|
|
243
249
|
Helpers to convert sats values to fiat and fiat values to sats.
|
|
244
250
|
|
|
251
|
+
##### getFiatCurrencies(): Promise<FiatCurrency[]>
|
|
252
|
+
|
|
253
|
+
Returns the list of available fiat currencies sorted by priority
|
|
254
|
+
|
|
245
255
|
##### getFiatValue(satoshi: number, currency: string): number
|
|
246
256
|
|
|
247
257
|
Returns the fiat value for a specified currency of a satoshi amount
|
|
@@ -257,6 +267,7 @@ Like `getFiatValue` but returns a formatted string for a given locale using Java
|
|
|
257
267
|
#### Examples
|
|
258
268
|
|
|
259
269
|
```js
|
|
270
|
+
await fiat.getFiatCurrencies();
|
|
260
271
|
await fiat.getFiatValue({ satoshi: 2100, currency: "eur" });
|
|
261
272
|
await fiat.getSatoshiValue({ amount: 100, currency: "eur" }); // for 1 EUR
|
|
262
273
|
await fiat.getFormattedFiatValue({
|
package/dist/cjs/fiat.cjs
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const numSatsInBtc = 100000000;
|
|
4
|
+
const getFiatCurrencies = async () => {
|
|
5
|
+
const url = "https://getalby.com/api/rates";
|
|
6
|
+
const response = await fetch(url);
|
|
7
|
+
if (!response.ok) {
|
|
8
|
+
throw new Error(`Failed to fetch currencies: ${response.status} ${response.statusText}`);
|
|
9
|
+
}
|
|
10
|
+
const data = await response.json();
|
|
11
|
+
const mappedCurrencies = Object.entries(data)
|
|
12
|
+
.filter(([code]) => code.toUpperCase() !== "BTC")
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
.map(([code, details]) => ({
|
|
15
|
+
code: code.toUpperCase(),
|
|
16
|
+
name: details.name,
|
|
17
|
+
priority: details.priority,
|
|
18
|
+
symbol: details.symbol,
|
|
19
|
+
}))
|
|
20
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
21
|
+
.sort((a, b) => a.priority - b.priority);
|
|
22
|
+
return mappedCurrencies;
|
|
23
|
+
};
|
|
4
24
|
const getFiatBtcRate = async (currency) => {
|
|
5
25
|
const url = "https://getalby.com/api/rates/" + currency.toLowerCase() + ".json";
|
|
6
26
|
const response = await fetch(url);
|
|
@@ -30,6 +50,7 @@ const getFormattedFiatValue = async ({ satoshi, currency, locale, }) => {
|
|
|
30
50
|
};
|
|
31
51
|
|
|
32
52
|
exports.getFiatBtcRate = getFiatBtcRate;
|
|
53
|
+
exports.getFiatCurrencies = getFiatCurrencies;
|
|
33
54
|
exports.getFiatValue = getFiatValue;
|
|
34
55
|
exports.getFormattedFiatValue = getFormattedFiatValue;
|
|
35
56
|
exports.getSatoshiValue = getSatoshiValue;
|
package/dist/cjs/fiat.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat.cjs","sources":["../../src/fiat/fiat.ts"],"sourcesContent":["const numSatsInBtc = 100_000_000;\n\nexport const getFiatBtcRate = async (currency: string): Promise<number> => {\n const url =\n \"https://getalby.com/api/rates/\" + currency.toLowerCase() + \".json\";\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch rate: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n return data.rate_float / numSatsInBtc;\n};\n\nexport const getFiatValue = async ({\n satoshi,\n currency,\n}: {\n satoshi: number | string;\n currency: string;\n}) => {\n const rate = await getFiatBtcRate(currency);\n\n return Number(satoshi) * rate;\n};\n\nexport const getSatoshiValue = async ({\n amount,\n currency,\n}: {\n amount: number | string;\n currency: string;\n}) => {\n const rate = await getFiatBtcRate(currency);\n\n return Math.floor(Number(amount) / rate);\n};\n\nexport const getFormattedFiatValue = async ({\n satoshi,\n currency,\n locale,\n}: {\n satoshi: number | string;\n currency: string;\n locale: string;\n}) => {\n if (!locale) {\n locale = \"en\";\n }\n const fiatValue = await getFiatValue({ satoshi, currency });\n return fiatValue.toLocaleString(locale, {\n style: \"currency\",\n currency,\n });\n};\n"],"names":[],"mappings":";;AAAA,MAAM,YAAY,GAAG,SAAW;
|
|
1
|
+
{"version":3,"file":"fiat.cjs","sources":["../../src/fiat/fiat.ts"],"sourcesContent":["const numSatsInBtc = 100_000_000;\n\nexport interface FiatCurrency {\n code: string;\n name: string;\n symbol: string;\n priority: number;\n}\n\nexport const getFiatCurrencies = async (): Promise<FiatCurrency[]> => {\n const url = \"https://getalby.com/api/rates\";\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch currencies: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n const mappedCurrencies: FiatCurrency[] = Object.entries(data)\n .filter(([code]) => code.toUpperCase() !== \"BTC\")\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map(([code, details]: any) => ({\n code: code.toUpperCase(),\n name: details.name,\n priority: details.priority,\n symbol: details.symbol,\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n .sort((a, b) => a.priority - b.priority) as FiatCurrency[];\n\n return mappedCurrencies;\n};\n\nexport const getFiatBtcRate = async (currency: string): Promise<number> => {\n const url =\n \"https://getalby.com/api/rates/\" + currency.toLowerCase() + \".json\";\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch rate: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n return data.rate_float / numSatsInBtc;\n};\n\nexport const getFiatValue = async ({\n satoshi,\n currency,\n}: {\n satoshi: number | string;\n currency: string;\n}) => {\n const rate = await getFiatBtcRate(currency);\n\n return Number(satoshi) * rate;\n};\n\nexport const getSatoshiValue = async ({\n amount,\n currency,\n}: {\n amount: number | string;\n currency: string;\n}) => {\n const rate = await getFiatBtcRate(currency);\n\n return Math.floor(Number(amount) / rate);\n};\n\nexport const getFormattedFiatValue = async ({\n satoshi,\n currency,\n locale,\n}: {\n satoshi: number | string;\n currency: string;\n locale: string;\n}) => {\n if (!locale) {\n locale = \"en\";\n }\n const fiatValue = await getFiatValue({ satoshi, currency });\n return fiatValue.toLocaleString(locale, {\n style: \"currency\",\n currency,\n });\n};\n"],"names":[],"mappings":";;AAAA,MAAM,YAAY,GAAG,SAAW;AASzB,MAAM,iBAAiB,GAAG,YAAoC;IACnE,MAAM,GAAG,GAAG,+BAA+B;AAC3C,IAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC;AAEjC,IAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AAChB,QAAA,MAAM,IAAI,KAAK,CACb,CAAA,4BAAA,EAA+B,QAAQ,CAAC,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAC,UAAU,CAAA,CAAE,CACxE;IACH;AAEA,IAAA,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;AAClC,IAAA,MAAM,gBAAgB,GAAmB,MAAM,CAAC,OAAO,CAAC,IAAI;AACzD,SAAA,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK;;SAE/C,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAM,MAAM;AAC9B,QAAA,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;AACvB,KAAA,CAAC;AACD,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAmB;AAE5D,IAAA,OAAO,gBAAgB;AACzB;MAEa,cAAc,GAAG,OAAO,QAAgB,KAAqB;IACxE,MAAM,GAAG,GACP,gCAAgC,GAAG,QAAQ,CAAC,WAAW,EAAE,GAAG,OAAO;AACrE,IAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC;AAEjC,IAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AAChB,QAAA,MAAM,IAAI,KAAK,CACb,CAAA,sBAAA,EAAyB,QAAQ,CAAC,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAC,UAAU,CAAA,CAAE,CAClE;IACH;AAEA,IAAA,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;AAElC,IAAA,OAAO,IAAI,CAAC,UAAU,GAAG,YAAY;AACvC;AAEO,MAAM,YAAY,GAAG,OAAO,EACjC,OAAO,EACP,QAAQ,GAIT,KAAI;AACH,IAAA,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC;AAE3C,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI;AAC/B;AAEO,MAAM,eAAe,GAAG,OAAO,EACpC,MAAM,EACN,QAAQ,GAIT,KAAI;AACH,IAAA,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC;IAE3C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAC1C;AAEO,MAAM,qBAAqB,GAAG,OAAO,EAC1C,OAAO,EACP,QAAQ,EACR,MAAM,GAKP,KAAI;IACH,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,GAAG,IAAI;IACf;IACA,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC3D,IAAA,OAAO,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE;AACtC,QAAA,KAAK,EAAE,UAAU;QACjB,QAAQ;AACT,KAAA,CAAC;AACJ;;;;;;;;"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1693,17 +1693,21 @@ const parseL402 = (input) => {
|
|
|
1693
1693
|
}
|
|
1694
1694
|
return keyValuePairs;
|
|
1695
1695
|
};
|
|
1696
|
+
const makeAuthenticateHeader = (args) => {
|
|
1697
|
+
const key = args.key || "L402";
|
|
1698
|
+
return `${key} macaroon="${args.macaroon}", invoice="${args.invoice}"`;
|
|
1699
|
+
};
|
|
1696
1700
|
|
|
1697
1701
|
const memoryStorage = new MemoryStorage();
|
|
1698
|
-
const HEADER_KEY = "L402";
|
|
1702
|
+
const HEADER_KEY = "L402";
|
|
1699
1703
|
const fetchWithL402 = async (url, fetchArgs, options) => {
|
|
1700
1704
|
if (!options) {
|
|
1701
1705
|
options = {};
|
|
1702
1706
|
}
|
|
1703
1707
|
const headerKey = options.headerKey || HEADER_KEY;
|
|
1704
|
-
const
|
|
1705
|
-
if (!
|
|
1706
|
-
throw new Error("
|
|
1708
|
+
const wallet = options.wallet;
|
|
1709
|
+
if (!wallet) {
|
|
1710
|
+
throw new Error("wallet is missing");
|
|
1707
1711
|
}
|
|
1708
1712
|
const store = options.store || memoryStorage;
|
|
1709
1713
|
if (!fetchArgs) {
|
|
@@ -1730,8 +1734,7 @@ const fetchWithL402 = async (url, fetchArgs, options) => {
|
|
|
1730
1734
|
const details = parseL402(header);
|
|
1731
1735
|
const token = details.token || details.macaroon;
|
|
1732
1736
|
const inv = details.invoice;
|
|
1733
|
-
await
|
|
1734
|
-
const invResp = await webln.sendPayment(inv);
|
|
1737
|
+
const invResp = await wallet.sendPayment(inv);
|
|
1735
1738
|
store.setItem(url, JSON.stringify({
|
|
1736
1739
|
token: token,
|
|
1737
1740
|
preimage: invResp.preimage,
|
|
@@ -1742,6 +1745,26 @@ const fetchWithL402 = async (url, fetchArgs, options) => {
|
|
|
1742
1745
|
};
|
|
1743
1746
|
|
|
1744
1747
|
const numSatsInBtc = 100000000;
|
|
1748
|
+
const getFiatCurrencies = async () => {
|
|
1749
|
+
const url = "https://getalby.com/api/rates";
|
|
1750
|
+
const response = await fetch(url);
|
|
1751
|
+
if (!response.ok) {
|
|
1752
|
+
throw new Error(`Failed to fetch currencies: ${response.status} ${response.statusText}`);
|
|
1753
|
+
}
|
|
1754
|
+
const data = await response.json();
|
|
1755
|
+
const mappedCurrencies = Object.entries(data)
|
|
1756
|
+
.filter(([code]) => code.toUpperCase() !== "BTC")
|
|
1757
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1758
|
+
.map(([code, details]) => ({
|
|
1759
|
+
code: code.toUpperCase(),
|
|
1760
|
+
name: details.name,
|
|
1761
|
+
priority: details.priority,
|
|
1762
|
+
symbol: details.symbol,
|
|
1763
|
+
}))
|
|
1764
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
1765
|
+
.sort((a, b) => a.priority - b.priority);
|
|
1766
|
+
return mappedCurrencies;
|
|
1767
|
+
};
|
|
1745
1768
|
const getFiatBtcRate = async (currency) => {
|
|
1746
1769
|
const url = "https://getalby.com/api/rates/" + currency.toLowerCase() + ".json";
|
|
1747
1770
|
const response = await fetch(url);
|
|
@@ -1782,11 +1805,13 @@ exports.fromHexString = fromHexString;
|
|
|
1782
1805
|
exports.generateZapEvent = generateZapEvent;
|
|
1783
1806
|
exports.getEventHash = getEventHash;
|
|
1784
1807
|
exports.getFiatBtcRate = getFiatBtcRate;
|
|
1808
|
+
exports.getFiatCurrencies = getFiatCurrencies;
|
|
1785
1809
|
exports.getFiatValue = getFiatValue;
|
|
1786
1810
|
exports.getFormattedFiatValue = getFormattedFiatValue;
|
|
1787
1811
|
exports.getSatoshiValue = getSatoshiValue;
|
|
1788
1812
|
exports.isUrl = isUrl;
|
|
1789
1813
|
exports.isValidAmount = isValidAmount;
|
|
1814
|
+
exports.makeAuthenticateHeader = makeAuthenticateHeader;
|
|
1790
1815
|
exports.parseKeysendResponse = parseKeysendResponse;
|
|
1791
1816
|
exports.parseL402 = parseL402;
|
|
1792
1817
|
exports.parseLnUrlPayResponse = parseLnUrlPayResponse;
|