applesauce-wallet-connect 3.0.0 → 3.1.0

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/dist/index.d.ts CHANGED
@@ -2,4 +2,4 @@ export * as Blueprints from "./blueprints/index.js";
2
2
  export * as Helpers from "./helpers/index.js";
3
3
  export * from "./wallet-connect.js";
4
4
  export * from "./wallet-service.js";
5
- export * from "./types.js";
5
+ export * from "./interop.js";
package/dist/index.js CHANGED
@@ -2,4 +2,4 @@ export * as Blueprints from "./blueprints/index.js";
2
2
  export * as Helpers from "./helpers/index.js";
3
3
  export * from "./wallet-connect.js";
4
4
  export * from "./wallet-service.js";
5
- export * from "./types.js";
5
+ export * from "./interop.js";
@@ -0,0 +1,35 @@
1
+ import { Filter, NostrEvent } from "nostr-tools";
2
+ import { ObservableInput } from "rxjs";
3
+ /** A method used to subscribe to events on a set of relays */
4
+ export type NostrSubscriptionMethod = (relays: string[], filters: Filter[]) => ObservableInput<NostrEvent | string>;
5
+ /** A method used for publishing an event, can return a Promise that completes when published or an Observable that completes when published*/
6
+ export type NostrPublishMethod = (relays: string[], event: NostrEvent) => Promise<any> | ObservableInput<any>;
7
+ /** A simple pool type that combines the subscription and publish methods */
8
+ export type NostrPool = {
9
+ subscription: NostrSubscriptionMethod;
10
+ publish: NostrPublishMethod;
11
+ };
12
+ /** Options for setting the subscription and publish methods */
13
+ export type NostrConnectionMethodsOptions = {
14
+ /** An optional method for subscribing to relays */
15
+ subscriptionMethod?: NostrSubscriptionMethod;
16
+ /** An optional method for publishing events */
17
+ publishMethod?: NostrPublishMethod;
18
+ /** An optional pool for connection methods */
19
+ pool?: NostrPool;
20
+ };
21
+ /** A class that implements has global fallback methods for subscription and publish methods */
22
+ export interface NostrConnectionClassMethods {
23
+ new (...args: any[]): any;
24
+ /** A fallback method to use for subscriptionMethod if none is passed in when creating the client */
25
+ subscriptionMethod: NostrSubscriptionMethod | undefined;
26
+ /** A fallback method to use for publishMethod if none is passed in when creating the client */
27
+ publishMethod: NostrPublishMethod | undefined;
28
+ /** A fallback pool to use if none is pass in when creating the signer */
29
+ pool: NostrPool | undefined;
30
+ }
31
+ /** Get the subscription and publish methods for a NostrConnect class */
32
+ export declare function getConnectionMethods(options: NostrConnectionMethodsOptions, cls?: NostrConnectionClassMethods): {
33
+ subscriptionMethod: NostrSubscriptionMethod;
34
+ publishMethod: NostrPublishMethod;
35
+ };
@@ -0,0 +1,19 @@
1
+ /** Get the subscription and publish methods for a NostrConnect class */
2
+ export function getConnectionMethods(options, cls) {
3
+ const subscriptionMethod = options.subscriptionMethod ||
4
+ options.pool?.subscription.bind(options.pool) ||
5
+ cls?.subscriptionMethod ||
6
+ cls?.pool?.subscription.bind(cls.pool);
7
+ if (!subscriptionMethod)
8
+ throw new Error("Missing subscriptionMethod, either pass a method or set subscriptionMethod globally on the class");
9
+ const publishMethod = options.publishMethod ||
10
+ options.pool?.publish.bind(options.pool) ||
11
+ cls?.publishMethod ||
12
+ cls?.pool?.publish.bind(cls.pool);
13
+ if (!publishMethod)
14
+ throw new Error("Missing publishMethod, either pass a method or set publishMethod globally on the class");
15
+ return {
16
+ subscriptionMethod,
17
+ publishMethod,
18
+ };
19
+ }
@@ -3,9 +3,9 @@ import { EventSigner } from "applesauce-factory";
3
3
  import { NostrEvent } from "nostr-tools";
4
4
  import { BehaviorSubject, Observable, Subscription } from "rxjs";
5
5
  import { GetBalanceResult, GetInfoResult, ListTransactionsResult, LookupInvoiceResult, MakeInvoiceParams, MakeInvoiceResult, NotificationType, PayInvoiceResult, PayKeysendResult, WalletAuthURI, WalletConnectEncryptionMethod, WalletConnectURI, WalletMethod, WalletNotification, WalletRequest, WalletResponse, WalletSupport } from "./helpers/index.js";
6
- import { NostrPool, NostrPublishMethod, NostrSubscriptionMethod } from "./types.js";
6
+ import { NostrConnectionMethodsOptions, NostrPool, NostrPublishMethod, NostrSubscriptionMethod } from "./interop.js";
7
7
  export type SerializedWalletConnect = WalletConnectURI;
8
- export type WalletConnectOptions = {
8
+ export type WalletConnectOptions = NostrConnectionMethodsOptions & {
9
9
  /** The secret to use for the connection */
10
10
  secret: Uint8Array;
11
11
  /** The relays to use for the connection */
@@ -14,12 +14,6 @@ export type WalletConnectOptions = {
14
14
  service?: string;
15
15
  /** Default timeout for RPC requests in milliseconds */
16
16
  timeout?: number;
17
- /** A method for subscribing to relays */
18
- subscriptionMethod?: NostrSubscriptionMethod;
19
- /** A method for publishing events */
20
- publishMethod?: NostrPublishMethod;
21
- /** An optional pool for connection methods */
22
- pool?: NostrPool;
23
17
  };
24
18
  export declare class WalletConnect {
25
19
  /** A fallback method to use for subscriptionMethod if none is passed in when creating the client */
@@ -2,10 +2,11 @@ import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
2
2
  import { simpleTimeout } from "applesauce-core";
3
3
  import { create } from "applesauce-factory";
4
4
  import { finalizeEvent, getPublicKey, nip04, nip44, verifyEvent } from "nostr-tools";
5
- import { BehaviorSubject, defer, filter, firstValueFrom, from, fromEvent, identity, ignoreElements, lastValueFrom, map, merge, mergeMap, ReplaySubject, share, switchMap, takeUntil, tap, timer, toArray, } from "rxjs";
5
+ import { BehaviorSubject, defer, filter, firstValueFrom, from, fromEvent, identity, ignoreElements, lastValueFrom, map, merge, mergeMap, repeat, ReplaySubject, retry, share, switchMap, takeUntil, tap, timer, toArray, } from "rxjs";
6
6
  import { WalletRequestBlueprint } from "./blueprints/index.js";
7
7
  import { createWalletError } from "./helpers/error.js";
8
8
  import { createWalletAuthURI, getPreferredEncryption, getWalletNotification, getWalletRequestEncryption, getWalletResponse, getWalletResponseRequestId, getWalletSupport, isWalletNotificationLocked, isWalletResponseLocked, parseWalletConnectURI, supportsMethod, supportsNotifications, supportsNotificationType, unlockWalletNotification, unlockWalletResponse, WALLET_INFO_KIND, WALLET_LEGACY_NOTIFICATION_KIND, WALLET_NOTIFICATION_KIND, WALLET_RESPONSE_KIND, } from "./helpers/index.js";
9
+ import { getConnectionMethods, } from "./interop.js";
9
10
  export class WalletConnect {
10
11
  /** A fallback method to use for subscriptionMethod if none is passed in when creating the client */
11
12
  static subscriptionMethod = undefined;
@@ -58,15 +59,7 @@ export class WalletConnect {
58
59
  },
59
60
  };
60
61
  // Get the subscription and publish methods
61
- const subscriptionMethod = options.subscriptionMethod ||
62
- options.pool?.subscription ||
63
- WalletConnect.subscriptionMethod ||
64
- WalletConnect.pool?.subscription;
65
- if (!subscriptionMethod)
66
- throw new Error("Missing subscriptionMethod, either pass a method or set WalletConnect.subscriptionMethod");
67
- const publishMethod = options.publishMethod || options.pool?.publish || WalletConnect.publishMethod || WalletConnect.pool?.publish;
68
- if (!publishMethod)
69
- throw new Error("Missing publishMethod, either pass a method or set WalletConnect.publishMethod");
62
+ const { subscriptionMethod, publishMethod } = getConnectionMethods(options, WalletConnect);
70
63
  // Use arrow functions so "this" isn't bound to the signer
71
64
  this.subscriptionMethod = (relays, filters) => subscriptionMethod(relays, filters);
72
65
  this.publishMethod = (relays, event) => publishMethod(relays, event);
@@ -75,10 +68,14 @@ export class WalletConnect {
75
68
  const client = getPublicKey(this.secret);
76
69
  // If the service is not known yet, subscribe to a wallet info event tagging the client
77
70
  if (!service)
78
- return this.subscriptionMethod(this.relays, [{ kinds: [WALLET_INFO_KIND], "#p": [client] }]).pipe(
71
+ return from(this.subscriptionMethod(this.relays, [{ kinds: [WALLET_INFO_KIND], "#p": [client] }])).pipe(
72
+ // Keep the connection open indefinitely
73
+ repeat(),
74
+ // Retry on connection failure
75
+ retry(),
79
76
  // Ignore strings (support for applesauce-relay)
80
77
  filter((event) => typeof event !== "string"));
81
- return this.subscriptionMethod(this.relays, [
78
+ return from(this.subscriptionMethod(this.relays, [
82
79
  // Subscribe to response events
83
80
  {
84
81
  kinds: [WALLET_RESPONSE_KIND, WALLET_NOTIFICATION_KIND, WALLET_LEGACY_NOTIFICATION_KIND],
@@ -87,7 +84,11 @@ export class WalletConnect {
87
84
  },
88
85
  // Subscribe to wallet info events
89
86
  { kinds: [WALLET_INFO_KIND], authors: [service] },
90
- ]).pipe(
87
+ ])).pipe(
88
+ // Keep the connection open indefinitely
89
+ repeat(),
90
+ // Retry on connection failure
91
+ retry(),
91
92
  // Ignore strings (support for applesauce-relay)
92
93
  filter((event) => typeof event !== "string"),
93
94
  // Only include events from the wallet service
@@ -1,13 +1,13 @@
1
1
  import { EventSigner } from "applesauce-factory";
2
2
  import { NostrEvent } from "nostr-tools";
3
3
  import { Observable, Subscription } from "rxjs";
4
+ import { WalletAuthURI } from "./helpers/auth-uri.js";
4
5
  import { WalletErrorCode } from "./helpers/error.js";
5
6
  import { NotificationType, WalletNotification } from "./helpers/notification.js";
6
7
  import { GetBalanceParams, GetInfoParams, ListTransactionsParams, LookupInvoiceParams, MakeInvoiceParams, MultiPayInvoiceParams, MultiPayKeysendParams, PayInvoiceParams, PayKeysendParams, WalletRequest } from "./helpers/request.js";
7
8
  import { GetBalanceResult, GetInfoResult, ListTransactionsResult, LookupInvoiceResult, MakeInvoiceResult, MultiPayInvoiceResult, MultiPayKeysendResult, PayInvoiceResult, PayKeysendResult, WalletResponse } from "./helpers/response.js";
8
9
  import { WalletSupport } from "./helpers/support.js";
9
- import { NostrPool, NostrPublishMethod, NostrSubscriptionMethod } from "./types.js";
10
- import { WalletAuthURI } from "./helpers/auth-uri.js";
10
+ import { NostrConnectionMethodsOptions, NostrPool, NostrPublishMethod, NostrSubscriptionMethod } from "./interop.js";
11
11
  /** Handler function for pay_invoice method */
12
12
  export type PayInvoiceHandler = (params: PayInvoiceParams) => Promise<PayInvoiceResult>;
13
13
  /** Handler function for multi_pay_invoice method */
@@ -45,7 +45,7 @@ export type SerializedWalletService = {
45
45
  relays: string[];
46
46
  };
47
47
  /** Options for creating a WalletService */
48
- export interface WalletServiceOptions {
48
+ export interface WalletServiceOptions extends NostrConnectionMethodsOptions {
49
49
  /** The relays to use for the service */
50
50
  relays: string[];
51
51
  /** The signer to use for creating and unlocking events */
@@ -58,12 +58,6 @@ export interface WalletServiceOptions {
58
58
  handlers: WalletServiceHandlers;
59
59
  /** An array of notifications this wallet supports */
60
60
  notifications?: NotificationType[];
61
- /** An optional method for subscribing to relays */
62
- subscriptionMethod?: NostrSubscriptionMethod;
63
- /** An optional method for publishing events */
64
- publishMethod?: NostrPublishMethod;
65
- /** An optional pool for connection methods */
66
- pool?: NostrPool;
67
61
  }
68
62
  /** NIP-47 Wallet Service implementation */
69
63
  export declare class WalletService {
@@ -1,14 +1,15 @@
1
1
  import { logger } from "applesauce-core";
2
2
  import { create } from "applesauce-factory";
3
3
  import { generateSecretKey, getPublicKey, verifyEvent } from "nostr-tools";
4
- import { filter, mergeMap, share } from "rxjs";
4
+ import { filter, from, mergeMap, repeat, retry, share } from "rxjs";
5
+ import { bytesToHex } from "@noble/hashes/utils";
5
6
  import { WalletLegacyNotificationBlueprint, WalletNotificationBlueprint } from "./blueprints/notification.js";
6
7
  import { WalletResponseBlueprint } from "./blueprints/response.js";
7
8
  import { WalletSupportBlueprint } from "./blueprints/support.js";
9
+ import { parseWalletAuthURI } from "./helpers/auth-uri.js";
8
10
  import { WalletBaseError } from "./helpers/error.js";
9
11
  import { getWalletRequest, isWalletRequestExpired, isWalletRequestLocked, unlockWalletRequest, WALLET_REQUEST_KIND, } from "./helpers/request.js";
10
- import { bytesToHex } from "@noble/hashes/utils";
11
- import { parseWalletAuthURI } from "./helpers/auth-uri.js";
12
+ import { getConnectionMethods, } from "./interop.js";
12
13
  /** NIP-47 Wallet Service implementation */
13
14
  export class WalletService {
14
15
  /** A fallback method to use for subscriptionMethod if none is passed in when creating the client */
@@ -56,15 +57,7 @@ export class WalletService {
56
57
  this.client = getPublicKey(this.secret);
57
58
  }
58
59
  // Get the subscription and publish methods
59
- const subscriptionMethod = options.subscriptionMethod ||
60
- options.pool?.subscription ||
61
- WalletService.subscriptionMethod ||
62
- WalletService.pool?.subscription;
63
- if (!subscriptionMethod)
64
- throw new Error("Missing subscriptionMethod, either pass a method or set WalletService.subscriptionMethod");
65
- const publishMethod = options.publishMethod || options.pool?.publish || WalletService.publishMethod || WalletService.pool?.publish;
66
- if (!publishMethod)
67
- throw new Error("Missing publishMethod, either pass a method or set WalletService.publishMethod");
60
+ const { subscriptionMethod, publishMethod } = getConnectionMethods(options, WalletService);
68
61
  // Use arrow functions so "this" isn't bound to the signer
69
62
  this.subscriptionMethod = (relays, filters) => subscriptionMethod(relays, filters);
70
63
  this.publishMethod = (relays, event) => publishMethod(relays, event);
@@ -91,13 +84,17 @@ export class WalletService {
91
84
  // Get our public key
92
85
  this.pubkey = await this.signer.getPublicKey();
93
86
  // Create shared request observable with ref counting and timer
94
- this.events$ = this.subscriptionMethod(this.relays, [
87
+ this.events$ = from(this.subscriptionMethod(this.relays, [
95
88
  {
96
89
  kinds: [WALLET_REQUEST_KIND],
97
90
  "#p": [this.pubkey], // Only requests directed to us
98
91
  authors: [this.client], // Only requests from the client
99
92
  },
100
- ]).pipe(
93
+ ])).pipe(
94
+ // Keep the connection open indefinitely
95
+ repeat(),
96
+ // Retry on connection failure
97
+ retry(),
101
98
  // Ignore strings (support for applesauce-relay)
102
99
  filter((event) => typeof event !== "string"),
103
100
  // Only include valid wallet request events
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-wallet-connect",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -58,9 +58,9 @@
58
58
  }
59
59
  },
60
60
  "dependencies": {
61
- "applesauce-core": "^3.0.0",
62
- "applesauce-factory": "^3.0.0",
63
- "nostr-tools": "^2.13",
61
+ "applesauce-core": "^3.1.0",
62
+ "applesauce-factory": "^3.1.0",
63
+ "nostr-tools": "~2.15",
64
64
  "@noble/hashes": "^1.7.1",
65
65
  "rxjs": "^7.8.1"
66
66
  },
package/dist/types.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { Filter, NostrEvent } from "nostr-tools";
2
- import { Observable } from "rxjs";
3
- /** A method used to subscribe to events on a set of relays */
4
- export type NostrSubscriptionMethod = (relays: string[], filters: Filter[]) => Observable<NostrEvent | string>;
5
- /** A method used for publishing an event, can return a Promise that completes when published or an Observable that completes when published*/
6
- export type NostrPublishMethod = (relays: string[], event: NostrEvent) => Promise<any> | Observable<any>;
7
- /** A simple pool type that combines the subscription and publish methods */
8
- export type NostrPool = {
9
- subscription: NostrSubscriptionMethod;
10
- publish: NostrPublishMethod;
11
- };
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};