applesauce-wallet-connect 0.0.0-next-20250808173123 → 0.0.0-next-20250828144630

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.
Files changed (79) hide show
  1. package/README.md +3 -3
  2. package/dist/blueprints/support.d.ts +1 -1
  3. package/dist/blueprints/support.js +4 -2
  4. package/dist/helpers/auth-uri.d.ts +44 -0
  5. package/dist/helpers/auth-uri.js +113 -0
  6. package/dist/helpers/connect-uri.d.ts +5 -0
  7. package/dist/helpers/connect-uri.js +6 -2
  8. package/dist/helpers/index.d.ts +1 -0
  9. package/dist/helpers/index.js +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/interop.d.ts +35 -0
  13. package/dist/interop.js +19 -0
  14. package/dist/types.d.ts +5 -0
  15. package/dist/wallet-connect.d.ts +25 -14
  16. package/dist/wallet-connect.js +95 -34
  17. package/dist/wallet-service.d.ts +19 -10
  18. package/dist/wallet-service.js +40 -20
  19. package/package.json +4 -4
  20. package/dist/actions/index.d.ts +0 -1
  21. package/dist/actions/index.js +0 -1
  22. package/dist/actions/tokens.d.ts +0 -17
  23. package/dist/actions/tokens.js +0 -110
  24. package/dist/actions/wallet.d.ts +0 -13
  25. package/dist/actions/wallet.js +0 -64
  26. package/dist/actions/zap-info.d.ts +0 -22
  27. package/dist/actions/zap-info.js +0 -83
  28. package/dist/actions/zaps.d.ts +0 -8
  29. package/dist/actions/zaps.js +0 -30
  30. package/dist/blueprints/history.d.ts +0 -4
  31. package/dist/blueprints/history.js +0 -11
  32. package/dist/blueprints/info.d.ts +0 -4
  33. package/dist/blueprints/info.js +0 -8
  34. package/dist/blueprints/tokens.d.ts +0 -7
  35. package/dist/blueprints/tokens.js +0 -11
  36. package/dist/blueprints/wallet.d.ts +0 -5
  37. package/dist/blueprints/wallet.js +0 -11
  38. package/dist/blueprints/zaps.d.ts +0 -8
  39. package/dist/blueprints/zaps.js +0 -12
  40. package/dist/helpers/animated-qr.d.ts +0 -30
  41. package/dist/helpers/animated-qr.js +0 -71
  42. package/dist/helpers/history.d.ts +0 -26
  43. package/dist/helpers/history.js +0 -47
  44. package/dist/helpers/info.d.ts +0 -34
  45. package/dist/helpers/info.js +0 -97
  46. package/dist/helpers/methods.d.ts +0 -1
  47. package/dist/helpers/methods.js +0 -1
  48. package/dist/helpers/nutzap.d.ts +0 -27
  49. package/dist/helpers/nutzap.js +0 -66
  50. package/dist/helpers/tokens.d.ts +0 -58
  51. package/dist/helpers/tokens.js +0 -162
  52. package/dist/helpers/wallet.d.ts +0 -15
  53. package/dist/helpers/wallet.js +0 -41
  54. package/dist/helpers/zap-info.d.ts +0 -19
  55. package/dist/helpers/zap-info.js +0 -42
  56. package/dist/interface.d.ts +0 -6
  57. package/dist/interface.js +0 -1
  58. package/dist/models/history.d.ts +0 -6
  59. package/dist/models/history.js +0 -21
  60. package/dist/models/index.d.ts +0 -4
  61. package/dist/models/index.js +0 -4
  62. package/dist/models/nutzap.d.ts +0 -6
  63. package/dist/models/nutzap.js +0 -16
  64. package/dist/models/tokens.d.ts +0 -6
  65. package/dist/models/tokens.js +0 -58
  66. package/dist/models/wallet.d.ts +0 -13
  67. package/dist/models/wallet.js +0 -18
  68. package/dist/operations/history.d.ts +0 -7
  69. package/dist/operations/history.js +0 -34
  70. package/dist/operations/index.d.ts +0 -5
  71. package/dist/operations/index.js +0 -5
  72. package/dist/operations/nutzap.d.ts +0 -14
  73. package/dist/operations/nutzap.js +0 -33
  74. package/dist/operations/tokens.d.ts +0 -4
  75. package/dist/operations/tokens.js +0 -24
  76. package/dist/operations/wallet.d.ts +0 -8
  77. package/dist/operations/wallet.js +0 -30
  78. package/dist/operations/zap-info.d.ts +0 -10
  79. package/dist/operations/zap-info.js +0 -17
@@ -1,12 +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 { NostrPublishMethod, NostrSubscriptionMethod } from "./types.js";
10
+ import { NostrConnectionMethodsOptions, NostrPool, NostrPublishMethod, NostrSubscriptionMethod } from "./interop.js";
10
11
  /** Handler function for pay_invoice method */
11
12
  export type PayInvoiceHandler = (params: PayInvoiceParams) => Promise<PayInvoiceResult>;
12
13
  /** Handler function for multi_pay_invoice method */
@@ -37,22 +38,26 @@ export interface WalletServiceHandlers {
37
38
  get_balance?: GetBalanceHandler;
38
39
  get_info?: GetInfoHandler;
39
40
  }
41
+ export type SerializedWalletService = {
42
+ /** The client's public key */
43
+ client: string;
44
+ /** The relays to use for the service */
45
+ relays: string[];
46
+ };
40
47
  /** Options for creating a WalletService */
41
- export interface WalletServiceOptions {
48
+ export interface WalletServiceOptions extends NostrConnectionMethodsOptions {
42
49
  /** The relays to use for the service */
43
50
  relays: string[];
44
51
  /** The signer to use for creating and unlocking events */
45
52
  signer: EventSigner;
46
53
  /** The client's secret key */
47
54
  secret?: Uint8Array;
55
+ /** The client's public key (used for restoring the service) */
56
+ client?: string;
48
57
  /** Map of method handlers */
49
58
  handlers: WalletServiceHandlers;
50
59
  /** An array of notifications this wallet supports */
51
60
  notifications?: NotificationType[];
52
- /** An optional method for subscribing to relays */
53
- subscriptionMethod?: NostrSubscriptionMethod;
54
- /** An optional method for publishing events */
55
- publishMethod?: NostrPublishMethod;
56
61
  }
57
62
  /** NIP-47 Wallet Service implementation */
58
63
  export declare class WalletService {
@@ -60,6 +65,8 @@ export declare class WalletService {
60
65
  static subscriptionMethod: NostrSubscriptionMethod | undefined;
61
66
  /** A fallback method to use for publishMethod if none is passed in when creating the client */
62
67
  static publishMethod: NostrPublishMethod | undefined;
68
+ /** A fallback pool to use if none is pass in when creating the signer */
69
+ static pool: NostrPool | undefined;
63
70
  /** A method for subscribing to relays */
64
71
  protected readonly subscriptionMethod: NostrSubscriptionMethod;
65
72
  /** A method for publishing events */
@@ -77,14 +84,14 @@ export declare class WalletService {
77
84
  pubkey: string | null;
78
85
  /** The client's secret key */
79
86
  protected secret: Uint8Array;
87
+ /** The client's public key */
88
+ client: string;
80
89
  /** Shared observable for all wallet request events */
81
90
  protected events$: Observable<NostrEvent> | null;
82
91
  /** Subscription to the events observable */
83
92
  protected subscription: Subscription | null;
84
93
  /** Whether the service is currently running */
85
94
  running: boolean;
86
- /** Get the clients public key */
87
- get client(): string;
88
95
  constructor(options: WalletServiceOptions);
89
96
  /** Start the wallet service */
90
97
  start(): Promise<void>;
@@ -92,8 +99,8 @@ export declare class WalletService {
92
99
  stop(): void;
93
100
  /** Check if the service is running */
94
101
  isRunning(): boolean;
95
- /** Get the connection string for the service */
96
- getConnectionString(): string;
102
+ /** Get the connection URI for the service */
103
+ getConnectURI(): string;
97
104
  /** Send a notification to the client */
98
105
  notify<T extends WalletNotification>(type: T["notification_type"], notification: T["notification"], legacy?: boolean): Promise<void>;
99
106
  /** Publish the wallet support event */
@@ -108,4 +115,6 @@ export declare class WalletService {
108
115
  protected sendErrorResponse(requestEvent: NostrEvent, errorType: WalletErrorCode, errorMessage: string): Promise<void>;
109
116
  /** Send a response event */
110
117
  protected sendResponse(requestEvent: NostrEvent, response: WalletResponse): Promise<void>;
118
+ /** Creates a service for a nostr+walletauth URI */
119
+ static fromAuthURI(uri: string | WalletAuthURI, options: Omit<WalletServiceOptions, "relays">): WalletService;
111
120
  }
@@ -1,19 +1,23 @@
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";
12
+ import { getConnectionMethods, } from "./interop.js";
11
13
  /** NIP-47 Wallet Service implementation */
12
14
  export class WalletService {
13
15
  /** A fallback method to use for subscriptionMethod if none is passed in when creating the client */
14
16
  static subscriptionMethod = undefined;
15
17
  /** A fallback method to use for publishMethod if none is passed in when creating the client */
16
18
  static publishMethod = undefined;
19
+ /** A fallback pool to use if none is pass in when creating the signer */
20
+ static pool = undefined;
17
21
  /** A method for subscribing to relays */
18
22
  subscriptionMethod;
19
23
  /** A method for publishing events */
@@ -31,29 +35,32 @@ export class WalletService {
31
35
  pubkey = null;
32
36
  /** The client's secret key */
33
37
  secret;
38
+ /** The client's public key */
39
+ client;
34
40
  /** Shared observable for all wallet request events */
35
41
  events$ = null;
36
42
  /** Subscription to the events observable */
37
43
  subscription = null;
38
44
  /** Whether the service is currently running */
39
45
  running = false;
40
- /** Get the clients public key */
41
- get client() {
42
- return getPublicKey(this.secret);
43
- }
44
46
  constructor(options) {
45
47
  this.relays = options.relays;
46
48
  this.signer = options.signer;
47
49
  this.handlers = options.handlers;
48
- this.secret = options.secret ?? generateSecretKey();
49
- const subscriptionMethod = options.subscriptionMethod || WalletService.subscriptionMethod;
50
- if (!subscriptionMethod)
51
- throw new Error("Missing subscriptionMethod, either pass a method or set WalletService.subscriptionMethod");
52
- const publishMethod = options.publishMethod || WalletService.publishMethod;
53
- if (!publishMethod)
54
- throw new Error("Missing publishMethod, either pass a method or set WalletService.publishMethod");
55
- this.subscriptionMethod = subscriptionMethod;
56
- this.publishMethod = publishMethod;
50
+ // Set the client's secret and public key
51
+ if (options.secret) {
52
+ this.secret = options.secret;
53
+ this.client = getPublicKey(this.secret);
54
+ }
55
+ else {
56
+ this.secret = generateSecretKey();
57
+ this.client = getPublicKey(this.secret);
58
+ }
59
+ // Get the subscription and publish methods
60
+ const { subscriptionMethod, publishMethod } = getConnectionMethods(options, WalletService);
61
+ // Use arrow functions so "this" isn't bound to the signer
62
+ this.subscriptionMethod = (relays, filters) => subscriptionMethod(relays, filters);
63
+ this.publishMethod = (relays, event) => publishMethod(relays, event);
57
64
  const encryption = [];
58
65
  if (options.signer.nip04)
59
66
  encryption.push("nip04");
@@ -77,13 +84,17 @@ export class WalletService {
77
84
  // Get our public key
78
85
  this.pubkey = await this.signer.getPublicKey();
79
86
  // Create shared request observable with ref counting and timer
80
- this.events$ = this.subscriptionMethod(this.relays, [
87
+ this.events$ = from(this.subscriptionMethod(this.relays, [
81
88
  {
82
89
  kinds: [WALLET_REQUEST_KIND],
83
90
  "#p": [this.pubkey], // Only requests directed to us
84
91
  authors: [this.client], // Only requests from the client
85
92
  },
86
- ]).pipe(
93
+ ])).pipe(
94
+ // Keep the connection open indefinitely
95
+ repeat(),
96
+ // Retry on connection failure
97
+ retry(),
87
98
  // Ignore strings (support for applesauce-relay)
88
99
  filter((event) => typeof event !== "string"),
89
100
  // Only include valid wallet request events
@@ -116,8 +127,8 @@ export class WalletService {
116
127
  isRunning() {
117
128
  return this.running;
118
129
  }
119
- /** Get the connection string for the service */
120
- getConnectionString() {
130
+ /** Get the connection URI for the service */
131
+ getConnectURI() {
121
132
  if (!this.pubkey)
122
133
  throw new Error("Service is not running");
123
134
  if (!this.relays.length)
@@ -141,7 +152,7 @@ export class WalletService {
141
152
  /** Publish the wallet support event */
142
153
  async publishSupportEvent() {
143
154
  try {
144
- const draft = await create({ signer: this.signer }, WalletSupportBlueprint, this.support);
155
+ const draft = await create({ signer: this.signer }, WalletSupportBlueprint, this.support, this.client);
145
156
  const event = await this.signer.signEvent(draft);
146
157
  await this.publishMethod(this.relays, event);
147
158
  }
@@ -267,4 +278,13 @@ export class WalletService {
267
278
  throw error;
268
279
  }
269
280
  }
281
+ /** Creates a service for a nostr+walletauth URI */
282
+ static fromAuthURI(uri, options) {
283
+ const { client, relays } = typeof uri === "string" ? parseWalletAuthURI(uri) : uri;
284
+ return new WalletService({
285
+ ...options,
286
+ client,
287
+ relays,
288
+ });
289
+ }
270
290
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-wallet-connect",
3
- "version": "0.0.0-next-20250808173123",
3
+ "version": "0.0.0-next-20250828144630",
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": "0.0.0-next-20250808173123",
62
- "applesauce-factory": "0.0.0-next-20250808173123",
63
- "nostr-tools": "^2.13",
61
+ "applesauce-core": "0.0.0-next-20250828144630",
62
+ "applesauce-factory": "0.0.0-next-20250828144630",
63
+ "nostr-tools": "~2.15",
64
64
  "@noble/hashes": "^1.7.1",
65
65
  "rxjs": "^7.8.1"
66
66
  },
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,17 +0,0 @@
1
- import { Token } from "@cashu/cashu-ts";
2
- import { Action } from "applesauce-actions";
3
- import { NostrEvent } from "nostr-tools";
4
- /**
5
- * Adds a cashu token to the wallet and marks a list of nutzaps as redeemed
6
- * @param token the cashu token to add
7
- * @param redeemed an array of nutzap event ids to mark as redeemed
8
- */
9
- export declare function ReceiveToken(token: Token, redeemed?: string[], fee?: number): Action;
10
- /** An action that deletes old tokens and creates a new one but does not add a history event */
11
- export declare function RolloverTokens(tokens: NostrEvent[], token: Token): Action;
12
- /** An action that deletes old token events and adds a spend history item */
13
- export declare function CompleteSpend(spent: NostrEvent[], change: Token): Action;
14
- /** Combines all unlocked token events into a single event per mint */
15
- export declare function ConsolidateTokens(opts?: {
16
- ignoreLocked?: boolean;
17
- }): Action;
@@ -1,110 +0,0 @@
1
- import { CashuMint, CashuWallet, CheckStateEnum } from "@cashu/cashu-ts";
2
- import { DeleteBlueprint } from "applesauce-factory/blueprints";
3
- import { getTokenContent, ignoreDuplicateProofs, isTokenContentLocked, WALLET_TOKEN_KIND } from "../helpers/tokens.js";
4
- import { WalletTokenBlueprint } from "../blueprints/tokens.js";
5
- import { WalletHistoryBlueprint } from "../blueprints/history.js";
6
- /**
7
- * Adds a cashu token to the wallet and marks a list of nutzaps as redeemed
8
- * @param token the cashu token to add
9
- * @param redeemed an array of nutzap event ids to mark as redeemed
10
- */
11
- export function ReceiveToken(token, redeemed, fee) {
12
- return async function* ({ factory }) {
13
- const amount = token.proofs.reduce((t, p) => t + p.amount, 0);
14
- const tokenEvent = await factory.sign(await factory.create(WalletTokenBlueprint, token, []));
15
- const history = await factory.sign(await factory.create(WalletHistoryBlueprint, { direction: "in", amount, mint: token.mint, created: [tokenEvent.id], fee }, redeemed ?? []));
16
- yield tokenEvent;
17
- yield history;
18
- };
19
- }
20
- /** An action that deletes old tokens and creates a new one but does not add a history event */
21
- export function RolloverTokens(tokens, token) {
22
- return async function* ({ factory }) {
23
- // create a delete event for old tokens
24
- const deleteDraft = await factory.create(DeleteBlueprint, tokens);
25
- // create a new token event
26
- const tokenDraft = await factory.create(WalletTokenBlueprint, token, tokens.map((e) => e.id));
27
- // sign events
28
- const signedDelete = await factory.sign(deleteDraft);
29
- const signedToken = await factory.sign(tokenDraft);
30
- // publish events
31
- yield signedDelete;
32
- yield signedToken;
33
- };
34
- }
35
- /** An action that deletes old token events and adds a spend history item */
36
- export function CompleteSpend(spent, change) {
37
- return async function* ({ factory }) {
38
- if (spent.length === 0)
39
- throw new Error("Cant complete spent with no token events");
40
- if (spent.some((s) => isTokenContentLocked(s)))
41
- throw new Error("Cant complete spend with locked tokens");
42
- // create the nip-09 delete event for previous events
43
- const deleteDraft = await factory.create(DeleteBlueprint, spent);
44
- const changeAmount = change.proofs.reduce((t, p) => t + p.amount, 0);
45
- // create a new token event if needed
46
- const changeDraft = changeAmount > 0
47
- ? await factory.create(WalletTokenBlueprint, change, spent.map((e) => e.id))
48
- : undefined;
49
- const total = spent.reduce((total, token) => total + getTokenContent(token).proofs.reduce((t, p) => t + p.amount, 0), 0);
50
- // calculate the amount that was spent
51
- const diff = total - changeAmount;
52
- // sign delete and token
53
- const signedDelete = await factory.sign(deleteDraft);
54
- const signedToken = changeDraft && (await factory.sign(changeDraft));
55
- // create a history entry
56
- const history = await factory.create(WalletHistoryBlueprint, { direction: "out", mint: change.mint, amount: diff, created: signedToken ? [signedToken.id] : [] }, []);
57
- // sign history
58
- const signedHistory = await factory.sign(history);
59
- // publish events
60
- yield signedDelete;
61
- if (signedToken)
62
- yield signedToken;
63
- yield signedHistory;
64
- };
65
- }
66
- /** Combines all unlocked token events into a single event per mint */
67
- export function ConsolidateTokens(opts) {
68
- return async function* ({ events, factory, self }) {
69
- const tokens = Array.from(events.getByFilters({ kinds: [WALLET_TOKEN_KIND], authors: [self] })).filter((token) => {
70
- if (isTokenContentLocked(token)) {
71
- if (opts?.ignoreLocked)
72
- return false;
73
- else
74
- throw new Error("Token is locked");
75
- }
76
- else
77
- return true;
78
- });
79
- const byMint = tokens.reduce((map, token) => {
80
- const mint = getTokenContent(token).mint;
81
- if (!map.has(mint))
82
- map.set(mint, []);
83
- map.get(mint).push(token);
84
- return map;
85
- }, new Map());
86
- // loop over each mint and consolidate proofs
87
- for (const [mint, tokens] of byMint) {
88
- const cashuMint = new CashuMint(mint);
89
- const cashuWallet = new CashuWallet(cashuMint);
90
- // get all tokens proofs
91
- const proofs = tokens
92
- .map((t) => getTokenContent(t).proofs)
93
- .flat()
94
- // filter out duplicate proofs
95
- .filter(ignoreDuplicateProofs());
96
- // NOTE: this assumes that the states array is the same length and order as the proofs array
97
- const states = await cashuWallet.checkProofsStates(proofs);
98
- const notSpent = proofs.filter((_, i) => states[i].state !== CheckStateEnum.SPENT);
99
- // create delete and token event
100
- const deleteDraft = await factory.create(DeleteBlueprint, tokens);
101
- const tokenDraft = await factory.create(WalletTokenBlueprint, { mint, proofs: notSpent }, tokens.map((t) => t.id));
102
- // sign events
103
- const signedToken = await factory.sign(tokenDraft);
104
- const signedDelete = await factory.sign(deleteDraft);
105
- // publish events for mint
106
- yield signedToken;
107
- yield signedDelete;
108
- }
109
- };
110
- }
@@ -1,13 +0,0 @@
1
- import { Action } from "applesauce-actions";
2
- /** An action that creates a new 17375 wallet event and 375 wallet backup */
3
- export declare function CreateWallet(mints: string[], privateKey?: Uint8Array): Action;
4
- /**
5
- * Adds a private key to a wallet event
6
- * @throws if the wallet does not exist or is locked
7
- */
8
- export declare function WalletAddPrivateKey(privateKey: Uint8Array): Action;
9
- /** Unlocks the wallet event and optionally the tokens and history events */
10
- export declare function UnlockWallet(unlock?: {
11
- history?: boolean;
12
- tokens?: boolean;
13
- }): Action;
@@ -1,64 +0,0 @@
1
- import { getWalletMints, getWalletPrivateKey, isWalletLocked, unlockWallet, WALLET_KIND } from "../helpers/wallet.js";
2
- import { WalletBackupBlueprint, WalletBlueprint } from "../blueprints/wallet.js";
3
- import { isTokenContentLocked, unlockTokenContent, WALLET_TOKEN_KIND } from "../helpers/tokens.js";
4
- import { isHistoryContentLocked, unlockHistoryContent, WALLET_HISTORY_KIND } from "../helpers/history.js";
5
- /** An action that creates a new 17375 wallet event and 375 wallet backup */
6
- export function CreateWallet(mints, privateKey) {
7
- return async function* ({ events, factory, self }) {
8
- const existing = events.getReplaceable(WALLET_KIND, self);
9
- if (existing)
10
- throw new Error("Wallet already exists");
11
- const wallet = await factory.sign(await factory.create(WalletBlueprint, mints, privateKey));
12
- const backup = await factory.sign(await factory.create(WalletBackupBlueprint, wallet));
13
- // publish the backup first
14
- yield backup;
15
- yield wallet;
16
- };
17
- }
18
- /**
19
- * Adds a private key to a wallet event
20
- * @throws if the wallet does not exist or is locked
21
- */
22
- export function WalletAddPrivateKey(privateKey) {
23
- return async function* ({ events, self, factory }) {
24
- const wallet = events.getReplaceable(WALLET_KIND, self);
25
- if (!wallet)
26
- throw new Error("Wallet does not exist");
27
- if (isWalletLocked(wallet))
28
- throw new Error("Wallet is locked");
29
- if (getWalletPrivateKey(wallet))
30
- throw new Error("Wallet already has a private key");
31
- const draft = await factory.create(WalletBlueprint, getWalletMints(wallet), privateKey);
32
- const signed = await factory.sign(draft);
33
- // create backup event for wallet
34
- const backup = await factory.sign(await factory.create(WalletBackupBlueprint, signed));
35
- // publish events
36
- yield backup;
37
- yield signed;
38
- };
39
- }
40
- /** Unlocks the wallet event and optionally the tokens and history events */
41
- export function UnlockWallet(unlock) {
42
- return async function* ({ events, self, factory }) {
43
- const signer = factory.context.signer;
44
- if (!signer)
45
- throw new Error("Missing signer");
46
- const wallet = events.getReplaceable(WALLET_KIND, self);
47
- if (!wallet)
48
- throw new Error("Wallet does not exist");
49
- if (isWalletLocked(wallet))
50
- await unlockWallet(wallet, signer);
51
- if (unlock?.tokens) {
52
- const tokens = events.getTimeline({ kinds: [WALLET_TOKEN_KIND], authors: [self] });
53
- for (const token of tokens)
54
- if (isTokenContentLocked(token))
55
- await unlockTokenContent(token, signer);
56
- }
57
- if (unlock?.history) {
58
- const history = events.getTimeline({ kinds: [WALLET_HISTORY_KIND], authors: [self] });
59
- for (const entry of history)
60
- if (isHistoryContentLocked(entry))
61
- await unlockHistoryContent(entry, signer);
62
- }
63
- };
64
- }
@@ -1,22 +0,0 @@
1
- import { Action } from "applesauce-actions";
2
- /** An action to add a relay to the kind 10019 nutzap info event */
3
- export declare function AddNutzapInfoRelay(relay: string | string[]): Action;
4
- /** An action to remove a relay from the kind 10019 nutzap info event */
5
- export declare function RemoveNutzapInfoRelay(relay: string | string[]): Action;
6
- /** An action to add a mint to the kind 10019 nutzap info event */
7
- export declare function AddNutzapInfoMint(mint: {
8
- url: string;
9
- units?: string[];
10
- } | Array<{
11
- url: string;
12
- units?: string[];
13
- }>): Action;
14
- /** An action to remove a mint from the kind 10019 nutzap info event */
15
- export declare function RemoveNutzapInfoMint(mint: string | string[]): Action;
16
- /** An action to set the pubkey for the kind 10019 nutzap info event */
17
- export declare function SetNutzapInfoPubkey(pubkey: string): Action;
18
- /** An action to update the entire nutzap info event */
19
- export declare function UpdateNutzapInfo(relays: string[], mints: Array<{
20
- url: string;
21
- units?: string[];
22
- }>, pubkey: string): Action;
@@ -1,83 +0,0 @@
1
- import { modifyPublicTags } from "applesauce-factory/operations";
2
- import { addNameValueTag, removeNameValueTag, setSingletonTag } from "applesauce-factory/operations/tag";
3
- import { NUTZAP_INFO_KIND } from "../helpers/zap-info.js";
4
- import { setNutzapInfoMints, setNutzapInfoPubkey, setNutzapInfoRelays } from "../operations/zap-info.js";
5
- /** An action to add a relay to the kind 10019 nutzap info event */
6
- export function AddNutzapInfoRelay(relay) {
7
- return async function* ({ events, factory, self }) {
8
- if (typeof relay === "string")
9
- relay = [relay];
10
- const operations = relay.map((r) => addNameValueTag(["relay", r], false));
11
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
12
- const draft = nutzapInfo
13
- ? await factory.modifyTags(nutzapInfo, ...operations)
14
- : await factory.build({ kind: NUTZAP_INFO_KIND }, modifyPublicTags(...operations));
15
- const signed = await factory.sign(draft);
16
- yield signed;
17
- };
18
- }
19
- /** An action to remove a relay from the kind 10019 nutzap info event */
20
- export function RemoveNutzapInfoRelay(relay) {
21
- return async function* ({ events, factory, self }) {
22
- if (typeof relay === "string")
23
- relay = [relay];
24
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
25
- if (!nutzapInfo)
26
- return;
27
- const draft = await factory.modifyTags(nutzapInfo, ...relay.map((r) => removeNameValueTag(["relay", r])));
28
- const signed = await factory.sign(draft);
29
- yield signed;
30
- };
31
- }
32
- /** An action to add a mint to the kind 10019 nutzap info event */
33
- export function AddNutzapInfoMint(mint) {
34
- return async function* ({ events, factory, self }) {
35
- const mints = Array.isArray(mint) ? mint : [mint];
36
- const operations = mints.map((m) => {
37
- const tag = m.units ? ["mint", m.url, ...m.units] : ["mint", m.url];
38
- return addNameValueTag(tag, false);
39
- });
40
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
41
- const draft = nutzapInfo
42
- ? await factory.modifyTags(nutzapInfo, ...operations)
43
- : await factory.build({ kind: NUTZAP_INFO_KIND }, modifyPublicTags(...operations));
44
- const signed = await factory.sign(draft);
45
- yield signed;
46
- };
47
- }
48
- /** An action to remove a mint from the kind 10019 nutzap info event */
49
- export function RemoveNutzapInfoMint(mint) {
50
- return async function* ({ events, factory, self }) {
51
- if (typeof mint === "string")
52
- mint = [mint];
53
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
54
- if (!nutzapInfo)
55
- return;
56
- const draft = await factory.modifyTags(nutzapInfo, ...mint.map((m) => removeNameValueTag(["mint", m])));
57
- const signed = await factory.sign(draft);
58
- yield signed;
59
- };
60
- }
61
- /** An action to set the pubkey for the kind 10019 nutzap info event */
62
- export function SetNutzapInfoPubkey(pubkey) {
63
- return async function* ({ events, factory, self }) {
64
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
65
- const draft = nutzapInfo
66
- ? await factory.modifyTags(nutzapInfo, setSingletonTag(["pubkey", pubkey], true))
67
- : await factory.build({ kind: NUTZAP_INFO_KIND }, modifyPublicTags(setSingletonTag(["pubkey", pubkey], true)));
68
- const signed = await factory.sign(draft);
69
- yield signed;
70
- };
71
- }
72
- /** An action to update the entire nutzap info event */
73
- export function UpdateNutzapInfo(relays, mints, pubkey) {
74
- return async function* ({ events, factory, self }) {
75
- const operations = [setNutzapInfoRelays(relays), setNutzapInfoMints(mints), setNutzapInfoPubkey(pubkey)];
76
- const nutzapInfo = events.getReplaceable(NUTZAP_INFO_KIND, self);
77
- const draft = nutzapInfo
78
- ? await factory.modify(nutzapInfo, ...operations)
79
- : await factory.build({ kind: NUTZAP_INFO_KIND }, ...operations);
80
- const signed = await factory.sign(draft);
81
- yield signed;
82
- };
83
- }
@@ -1,8 +0,0 @@
1
- import { Token } from "@cashu/cashu-ts";
2
- import { Action } from "applesauce-actions";
3
- import { NostrEvent } from "nostr-tools";
4
- import { ProfilePointer } from "nostr-tools/nip19";
5
- /** Creates a NIP-61 nutzap event for an event with a token */
6
- export declare function NutzapEvent(event: NostrEvent, token: Token, comment?: string): Action;
7
- /** Creates a NIP-61 nutzap event to a users profile */
8
- export declare function NutzapProfile(user: string | ProfilePointer, token: Token, comment?: string): Action;
@@ -1,30 +0,0 @@
1
- import { NutzapBlueprint, ProfileNutzapBlueprint } from "../blueprints/zaps.js";
2
- import { NUTZAP_INFO_KIND, verifyProofsLocked } from "../helpers/zap-info.js";
3
- /** Creates a NIP-61 nutzap event for an event with a token */
4
- export function NutzapEvent(event, token, comment) {
5
- return async function* ({ events, factory }) {
6
- const recipient = event.pubkey;
7
- const info = events.getReplaceable(NUTZAP_INFO_KIND, recipient);
8
- if (!info)
9
- throw new Error("Nutzap info not found");
10
- // Verify all tokens are p2pk locked
11
- verifyProofsLocked(token.proofs, info);
12
- // NOTE: Disabled because mints and units should be checked by the app before
13
- // const mints = getNutzapInfoMints(info);
14
- // if (!mints.some((m) => m.mint === token.mint)) throw new Error("Token mint not found in nutzap info");
15
- const nutzap = await factory.sign(await factory.create(NutzapBlueprint, event, token, comment || token.memo));
16
- yield nutzap;
17
- };
18
- }
19
- /** Creates a NIP-61 nutzap event to a users profile */
20
- export function NutzapProfile(user, token, comment) {
21
- return async function* ({ events, factory }) {
22
- const info = events.getReplaceable(NUTZAP_INFO_KIND, typeof user === "string" ? user : user.pubkey);
23
- if (!info)
24
- throw new Error("Nutzap info not found");
25
- // Verify all tokens are p2pk locked
26
- verifyProofsLocked(token.proofs, info);
27
- const nutzap = await factory.sign(await factory.create(ProfileNutzapBlueprint, user, token, comment || token.memo));
28
- yield nutzap;
29
- };
30
- }
@@ -1,4 +0,0 @@
1
- import { EventPointer } from "nostr-tools/nip19";
2
- import { HistoryContent } from "../helpers/history.js";
3
- /** A blueprint that creates a wallet history event */
4
- export declare function WalletHistoryBlueprint(content: HistoryContent, redeemed: (string | EventPointer)[]): import("applesauce-factory").EventBlueprint;
@@ -1,11 +0,0 @@
1
- import { blueprint } from "applesauce-factory";
2
- import { WALLET_HISTORY_KIND } from "../helpers/history.js";
3
- import { setHistoryContent, setHistoryRedeemed } from "../operations/history.js";
4
- /** A blueprint that creates a wallet history event */
5
- export function WalletHistoryBlueprint(content, redeemed) {
6
- return blueprint(WALLET_HISTORY_KIND,
7
- // set the encrypted tags on the event
8
- setHistoryContent(content),
9
- // set the public redeemed tags
10
- setHistoryRedeemed(redeemed));
11
- }
@@ -1,4 +0,0 @@
1
- import { EventBlueprint } from "applesauce-factory";
2
- import { WalletSupport } from "../helpers/support.js";
3
- /** Creates a wallet info event */
4
- export declare function WalletInfoBlueprint(info: WalletSupport): EventBlueprint;
@@ -1,8 +0,0 @@
1
- import { blueprint } from "applesauce-factory";
2
- import { setContent } from "applesauce-factory/operations/content";
3
- import { includeSingletonTag } from "applesauce-factory/operations";
4
- import { WALLET_INFO_KIND } from "../helpers/support.js";
5
- /** Creates a wallet info event */
6
- export function WalletInfoBlueprint(info) {
7
- return blueprint(WALLET_INFO_KIND, setContent(info.methods.join(" ")), info.encryption ? includeSingletonTag(["encryption", info.encryption.join(" ")]) : undefined, info.notifications ? includeSingletonTag(["notifications", info.notifications.join(" ")]) : undefined);
8
- }
@@ -1,7 +0,0 @@
1
- import { Token } from "@cashu/cashu-ts";
2
- /**
3
- * A blueprint for a wallet token event, takes a cashu token and previous deleted token event ids
4
- * @param token the cashu token to store
5
- * @param [del=[]] an array of previous token event ids that are deleted
6
- */
7
- export declare function WalletTokenBlueprint(token: Token, del?: string[]): import("applesauce-factory").EventBlueprint;
@@ -1,11 +0,0 @@
1
- import { blueprint } from "applesauce-factory";
2
- import { WALLET_TOKEN_KIND } from "../helpers/tokens.js";
3
- import { setToken } from "../operations/tokens.js";
4
- /**
5
- * A blueprint for a wallet token event, takes a cashu token and previous deleted token event ids
6
- * @param token the cashu token to store
7
- * @param [del=[]] an array of previous token event ids that are deleted
8
- */
9
- export function WalletTokenBlueprint(token, del = []) {
10
- return blueprint(WALLET_TOKEN_KIND, setToken(token, del));
11
- }