Skip to content

Commit

Permalink
Merge branch 'master' into fix/optional-preimage
Browse files Browse the repository at this point in the history
  • Loading branch information
reneaaron authored Nov 20, 2023
2 parents 1e58736 + 42b320d commit 328130f
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 33 deletions.
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ webln.close(); // close the websocket connection
```js
import { NostrWebLNProvider } from '@getalby/sdk';

const webln = new NostrWebLNProvider({ nostrWalletConnectUrl: 'nostrwalletconnect://69effe7b49a6dd5cf525bd0905917a5005ffe480b58eeb8e861418cf3ae760d9?relay=wss://nostr.bitcoiner.social&secret=c60320b3ecb6c15557510d1518ef41194e9f9337c82621ddef3f979f668bfebd'); // use defaults
const webln = new NostrWebLNProvider({ nostrWalletConnectUrl: 'nostr+walletconnect://69effe7b49a6dd5cf525bd0905917a5005ffe480b58eeb8e861418cf3ae760d9?relay=wss://nostr.bitcoiner.social&secret=c60320b3ecb6c15557510d1518ef41194e9f9337c82621ddef3f979f668bfebd'); // use defaults
await webln.enable(); // connect to the relay
const response = await webln.sendPayment(invoice);
console.log(response.preimage);
Expand Down Expand Up @@ -217,10 +217,11 @@ Please have a look a the Alby OAuth2 Wallet API:
- outgoingInvoices
- getInvoice
- createInvoice
- decodeInvoice
- keysend
- sendPayment
- sendBoostagram
- sendToAlbyAccount
- sendBoostagramToAlbyAccount
- createWebhookEndpoint
- deleteWebhookEndpoint
Expand Down Expand Up @@ -454,9 +455,12 @@ console.log(response.keysends);
For quick invoice decoding without an API request please see Alby's [Lightning Tools package](https://github.com/getAlby/js-lightning-tools#basic-invoice-decoding).
For more invoice details you can use the Alby Wallet API.
For more invoice details you can use the Alby Wallet API:
**COMING SOON**
```js
const decodedInvoice = await client.decodeInvoice(paymentRequest);
const {payment_hash, amount, description, ...} = decodedInvoice;
```
## fetch() dependency
Expand All @@ -481,10 +485,10 @@ You can find examples in the [examples/](examples/) directory.
We are happy to help, please contact us or create an issue.
- [Twitter: @getAlby](https://twitter.com/getAlby)
- [Telegram group](https://t.me/getAlby)
- support at getalby.com
- [Telegram Community Chat](https://t.me/getAlby)
- e-mail to support@getalby.com
- [bitcoin.design](https://bitcoin.design/) Slack community [#lightning-browser-extension](https://bitcoindesign.slack.com/archives/C02591ADXM2)
- Read the [Alby developer guide](https://guides.getalby.com/overall-guide/alby-for-developers/getting-started) to better understand how Alby packages and APIs can be used to power your app.
- Read the [Alby developer guide](https://guides.getalby.com/developer-guide) to better understand how Alby packages and APIs can be used to power your app.
## Thanks
Expand Down
35 changes: 35 additions & 0 deletions examples/decode-invoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
import { auth, Client } from "../dist/index.module.js";

const rl = readline.createInterface({ input, output });

const paymentRequest =
"lnbc10u1pj4t6w0pp54wm83znxp8xly6qzuff2z7u6585rnlcw9uduf2haa42qcz09f5wqdq023jhxapqd4jk6mccqzzsxqyz5vqsp5mlvjs8nktpz98s5dcrhsuelrz94kl2vjukvu789yzkewast6m00q9qyyssqupynqdv7e5y8nlul0trva5t97g7v3gwx7akhu2dvu4pn66eu2pr5zkcnegp8myz3wrpj9ht06pwyfn4dvpmnr96ejq6ygex43ymaffqq3gud4d";

const authClient = new auth.OAuth2User({
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
callback: "http://localhost:8080",
scopes: ["invoices:read"], // this scope isn't needed, but at least one scope is required to get an access token
token: {
access_token: undefined,
refresh_token: undefined,
expires_at: undefined,
}, // initialize with existing token
});

console.log(`Open the following URL and authenticate the app:`);
console.log(authClient.generateAuthURL());
console.log("----\n");

const code = await rl.question("Code: (localhost:8080?code=[THIS CODE]: ");
rl.close();

await authClient.requestAccessToken(code);
console.log(authClient.token);
const client = new Client(authClient);

const response = await client.decodeInvoice(paymentRequest);

console.log(JSON.stringify(response, null, 2));
2 changes: 1 addition & 1 deletion examples/nwc/get-balance.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { webln as providers } from "../../dist/index.module.js";
const rl = readline.createInterface({ input, output });

const nwcUrl = await rl.question(
"Nostr Wallet Connect URL (nostrwalletconnect://...): ",
"Nostr Wallet Connect URL (nostr+walletconnect://...): ",
);
rl.close();

Expand Down
2 changes: 1 addition & 1 deletion examples/nwc/lookup-invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { webln as providers } from "../../dist/index.module.js";
const rl = readline.createInterface({ input, output });

const nwcUrl = await rl.question(
"Nostr Wallet Connect URL (nostrwalletconnect://...): ",
"Nostr Wallet Connect URL (nostr+walletconnect://...): ",
);
rl.close();

Expand Down
2 changes: 1 addition & 1 deletion examples/nwc/make-invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { webln as providers } from "../../dist/index.module.js";
const rl = readline.createInterface({ input, output });

const nwcUrl = await rl.question(
"Nostr Wallet Connect URL (nostrwalletconnect://...): ",
"Nostr Wallet Connect URL (nostr+walletconnect://...): ",
);
rl.close();

Expand Down
2 changes: 1 addition & 1 deletion examples/nwc/send-payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { webln as providers } from "../../dist/index.module.js";
const rl = readline.createInterface({ input, output });

const nwcUrl = await rl.question(
"Nostr Wallet Connect URL (nostrwalletconnect://...): ",
"Nostr Wallet Connect URL (nostr+walletconnect://...): ",
);
const invoice = await rl.question("Lightning invoice: ");
rl.close();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
},
"dependencies": {
"crypto-js": "^4.1.1",
"nostr-tools": "1.13.1",
"nostr-tools": "^1.17.0",
"events": "^3.3.0"
},
"devDependencies": {
Expand Down
45 changes: 41 additions & 4 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CreateSwapResponse,
CreateWebhookEndpointParams,
CreateWebhookEndpointResponse,
DecodedInvoice,
GetAccountBalanceResponse,
GetAccountInformationResponse,
GetInvoicesRequestParams,
Expand All @@ -17,7 +18,7 @@ import {
SendBoostagramRequestParams,
SendPaymentRequestParams,
SendPaymentResponse,
SendToAlbyRequestParams,
SendBoostagramToAlbyRequestParams,
SwapInfoResponse,
} from "./types";

Expand All @@ -37,6 +38,7 @@ export class Client {
}

accountBalance(
// eslint-disable-next-line @typescript-eslint/ban-types
params: {},
request_options?: Partial<RequestOptions>,
): Promise<GetAccountBalanceResponse> {
Expand All @@ -50,7 +52,11 @@ export class Client {
});
}

accountSummary(params: {}, request_options?: Partial<RequestOptions>) {
accountSummary(
// eslint-disable-next-line @typescript-eslint/ban-types
params: {},
request_options?: Partial<RequestOptions>,
) {
return rest({
auth: this.auth,
...this.defaultRequestOptions,
Expand All @@ -62,6 +68,7 @@ export class Client {
}

accountInformation(
// eslint-disable-next-line @typescript-eslint/ban-types
params: {},
request_options?: Partial<RequestOptions>,
): Promise<GetAccountInformationResponse> {
Expand All @@ -75,7 +82,11 @@ export class Client {
});
}

accountValue4Value(params: {}, request_options?: Partial<RequestOptions>) {
accountValue4Value(
// eslint-disable-next-line @typescript-eslint/ban-types
params: {},
request_options?: Partial<RequestOptions>,
) {
return rest({
auth: this.auth,
...this.defaultRequestOptions,
Expand Down Expand Up @@ -141,6 +152,19 @@ export class Client {
});
}

decodeInvoice(
paymentRequest: string,
request_options?: Partial<RequestOptions>,
): Promise<DecodedInvoice> {
return rest({
auth: this.auth,
...this.defaultRequestOptions,
...request_options,
endpoint: `/decode/bolt11/${paymentRequest}`,
method: "GET",
});
}

createInvoice(
invoice: InvoiceRequestParams,
request_options?: Partial<RequestOptions>,
Expand Down Expand Up @@ -215,8 +239,21 @@ export class Client {
});
}

/**
* @deprecated please use sendBoostagramToAlbyAccount. Deprecated since v2.7.0. Will be removed in v3.0.0.
*/
sendToAlbyAccount(
args: SendToAlbyRequestParams,
args: SendBoostagramToAlbyRequestParams,
request_options?: Partial<RequestOptions>,
) {
console.warn(
"sendToAlbyAccount is deprecated. Please use sendBoostagramToAlbyAccount instead.",
);
return this.sendBoostagramToAlbyAccount(args, request_options);
}

sendBoostagramToAlbyAccount(
args: SendBoostagramToAlbyRequestParams,
request_options?: Partial<RequestOptions>,
) {
const params = {
Expand Down
29 changes: 28 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,20 @@ export type SendBoostagramRequestParams = {
amount: number;
};

export type SendToAlbyRequestParams = {
export type SendBoostagramToAlbyRequestParams = {
/**
* the keysend custom value found at https://getalby.com/node
*/
account: string;
amount: number;
memo?: string;
};

/**
* @deprecated please use SendBoostagramToAlbyRequestParams
*/
export type SendToAlbyRequestParams = SendBoostagramToAlbyRequestParams;

export type CreateWebhookEndpointParams = {
url: string;
description?: string;
Expand Down Expand Up @@ -257,4 +265,23 @@ export type GetAccountInformationResponse = {
nostr_pubkey?: string;
};

export type DecodedInvoice = {
currency: string;
/**
* unix timestamp in seconds
*/
created_at: number;
/**
* expiry from the created_at time in seconds (not a timestamp)
*/
expiry: number;
payee: string;
msatoshi: number;
description: string;
payment_hash: string;
min_final_cltv_expiry: number;
amount: number;
payee_alias: string;
};

export { AlbyResponseError, RequestOptions };
19 changes: 7 additions & 12 deletions src/webln/NostrWeblnProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,7 @@ export class NostrWebLNProvider implements WebLNProvider, Nip07Provider {

const requestInvoiceArgs: RequestInvoiceArgs | undefined =
typeof args === "object" ? (args as RequestInvoiceArgs) : undefined;
const amount = +(
requestInvoiceArgs?.amount ??
args as string | number);
const amount = +(requestInvoiceArgs?.amount ?? (args as string | number));

if (!amount) {
throw new Error("No amount specified");
Expand Down Expand Up @@ -496,24 +494,21 @@ export class NostrWebLNProvider implements WebLNProvider, Nip07Provider {
}
});

const pub = this.relay.publish(event);

function publishTimeout() {
//console.error(`Publish timeout: event ${event.id}`);
reject({ error: `Publish timeout: event ${event.id}` });
}
const publishTimeoutCheck = setTimeout(publishTimeout, 5000);

pub.on("failed", (reason: unknown) => {
//console.debug(`failed to publish to ${this.relay.url}: ${reason}`)
try {
await this.relay.publish(event);
clearTimeout(publishTimeoutCheck);
reject({ error: `Failed to publish request: ${reason}` });
});

pub.on("ok", () => {
//console.debug(`Event ${event.id} for ${invoice} published`);
} catch (error) {
//console.error(`Failed to publish to ${this.relay.url}`, error);
clearTimeout(publishTimeoutCheck);
});
reject({ error: `Failed to publish request: ${error}` });
}
})();
});
}
Expand Down
14 changes: 10 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,11 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"

"@noble/ciphers@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.2.0.tgz#a12cda60f3cf1ab5d7c77068c3711d2366649ed7"
integrity sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==

"@noble/curves@1.1.0", "@noble/curves@~1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d"
Expand Down Expand Up @@ -5916,11 +5921,12 @@ normalize-url@^6.0.1:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==

nostr-tools@1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.13.1.tgz#191298d85a977cc50790e1c1d1cb83b86d3a9656"
integrity sha512-DTwpbxTH1/ar+afWd4gmVdpHH8CF290kdaxi00Llra88SHE6e38XuyzlRABVTcrBaceLMnoDdHmV3x16MoEFJg==
nostr-tools@^1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.17.0.tgz#b6f62e32fedfd9e68ec0a7ce57f74c44fc768e8c"
integrity sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==
dependencies:
"@noble/ciphers" "0.2.0"
"@noble/curves" "1.1.0"
"@noble/hashes" "1.3.1"
"@scure/base" "1.1.1"
Expand Down

0 comments on commit 328130f

Please sign in to comment.