applesauce-wallet 0.0.0-next-20251209200210 → 0.0.0-next-20251231055351

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 (91) hide show
  1. package/dist/actions/common.d.ts +4 -0
  2. package/dist/actions/common.js +15 -0
  3. package/dist/actions/index.d.ts +3 -2
  4. package/dist/actions/index.js +3 -2
  5. package/dist/actions/mint-recomendation.d.ts +30 -0
  6. package/dist/actions/mint-recomendation.js +96 -0
  7. package/dist/actions/{zap-info.d.ts → nutzap-info.d.ts} +20 -3
  8. package/dist/actions/nutzap-info.js +117 -0
  9. package/dist/actions/nutzaps.d.ts +24 -0
  10. package/dist/actions/nutzaps.js +154 -0
  11. package/dist/actions/tokens.d.ts +77 -7
  12. package/dist/actions/tokens.js +332 -69
  13. package/dist/actions/wallet.d.ts +18 -3
  14. package/dist/actions/wallet.js +74 -32
  15. package/dist/blueprints/history.d.ts +1 -1
  16. package/dist/blueprints/history.js +1 -1
  17. package/dist/blueprints/index.d.ts +1 -0
  18. package/dist/blueprints/index.js +1 -0
  19. package/dist/blueprints/mint-recommendation.d.ts +16 -0
  20. package/dist/blueprints/mint-recommendation.js +11 -0
  21. package/dist/blueprints/wallet.d.ts +5 -1
  22. package/dist/blueprints/wallet.js +6 -3
  23. package/dist/casts/__register__.d.ts +22 -0
  24. package/dist/casts/__register__.js +52 -0
  25. package/dist/casts/index.d.ts +8 -0
  26. package/dist/casts/index.js +8 -0
  27. package/dist/casts/mint-info.d.ts +18 -0
  28. package/dist/casts/mint-info.js +42 -0
  29. package/dist/casts/mint-recommendation.d.ts +16 -0
  30. package/dist/casts/mint-recommendation.js +29 -0
  31. package/dist/casts/nutzap-info.d.ts +14 -0
  32. package/dist/casts/nutzap-info.js +22 -0
  33. package/dist/casts/nutzap.d.ts +16 -0
  34. package/dist/casts/nutzap.js +37 -0
  35. package/dist/casts/wallet-history.d.ts +16 -0
  36. package/dist/casts/wallet-history.js +40 -0
  37. package/dist/casts/wallet-token.d.ts +29 -0
  38. package/dist/casts/wallet-token.js +52 -0
  39. package/dist/casts/wallet.d.ts +27 -0
  40. package/dist/casts/wallet.js +62 -0
  41. package/dist/helpers/cashu.d.ts +21 -0
  42. package/dist/helpers/cashu.js +105 -0
  43. package/dist/helpers/couch.d.ts +11 -0
  44. package/dist/helpers/couch.js +1 -0
  45. package/dist/helpers/history.d.ts +5 -1
  46. package/dist/helpers/history.js +13 -4
  47. package/dist/helpers/index.d.ts +7 -1
  48. package/dist/helpers/index.js +7 -1
  49. package/dist/helpers/indexed-db-couch.d.ts +34 -0
  50. package/dist/helpers/indexed-db-couch.js +119 -0
  51. package/dist/helpers/local-storage-couch.d.ts +29 -0
  52. package/dist/helpers/local-storage-couch.js +78 -0
  53. package/dist/helpers/mint-info.d.ts +40 -0
  54. package/dist/helpers/mint-info.js +80 -0
  55. package/dist/helpers/mint-recommendation.d.ts +41 -0
  56. package/dist/helpers/mint-recommendation.js +54 -0
  57. package/dist/helpers/{zap-info.d.ts → nutzap-info.d.ts} +10 -1
  58. package/dist/helpers/{zap-info.js → nutzap-info.js} +22 -10
  59. package/dist/helpers/nutzap.d.ts +15 -0
  60. package/dist/helpers/nutzap.js +57 -3
  61. package/dist/helpers/tokens.d.ts +9 -18
  62. package/dist/helpers/tokens.js +64 -94
  63. package/dist/helpers/wallet.d.ts +16 -6
  64. package/dist/helpers/wallet.js +40 -14
  65. package/dist/index.d.ts +1 -0
  66. package/dist/index.js +1 -0
  67. package/dist/models/history.d.ts +1 -1
  68. package/dist/models/history.js +7 -10
  69. package/dist/models/index.d.ts +0 -1
  70. package/dist/models/index.js +0 -1
  71. package/dist/models/nutzap.d.ts +2 -0
  72. package/dist/models/nutzap.js +8 -0
  73. package/dist/models/tokens.d.ts +2 -2
  74. package/dist/models/tokens.js +14 -17
  75. package/dist/operations/history.js +1 -1
  76. package/dist/operations/index.d.ts +2 -1
  77. package/dist/operations/index.js +2 -1
  78. package/dist/operations/mint-recommendation.d.ts +13 -0
  79. package/dist/operations/mint-recommendation.js +26 -0
  80. package/dist/operations/nutzap-info.d.ts +21 -0
  81. package/dist/operations/nutzap-info.js +71 -0
  82. package/dist/operations/wallet.d.ts +10 -1
  83. package/dist/operations/wallet.js +33 -3
  84. package/package.json +37 -28
  85. package/dist/actions/zap-info.js +0 -83
  86. package/dist/actions/zaps.d.ts +0 -8
  87. package/dist/actions/zaps.js +0 -30
  88. package/dist/models/wallet.d.ts +0 -13
  89. package/dist/models/wallet.js +0 -21
  90. package/dist/operations/zap-info.d.ts +0 -10
  91. package/dist/operations/zap-info.js +0 -17
@@ -0,0 +1,105 @@
1
+ import { getDecodedToken, getEncodedToken } from "@cashu/cashu-ts";
2
+ import { safeParse } from "applesauce-core/helpers";
3
+ /** Internal method for creating a unique id for each proof */
4
+ export function getProofUID(proof) {
5
+ return proof.id + proof.amount + proof.C + proof.secret;
6
+ }
7
+ /**
8
+ * Extracts the P2PK locking pubkey from a proof's secret
9
+ * @param proof the cashu proof to extract the pubkey from
10
+ * @returns the pubkey, or undefined if not P2PK locked
11
+ */
12
+ export function getProofP2PKPubkey(proof) {
13
+ const secret = safeParse(proof.secret);
14
+ if (!secret)
15
+ return;
16
+ if (!Array.isArray(secret))
17
+ return;
18
+ if (secret[0] !== "P2PK")
19
+ return;
20
+ const proofPubkey = secret[1]?.data;
21
+ if (!proofPubkey || typeof proofPubkey !== "string")
22
+ return;
23
+ return proofPubkey;
24
+ }
25
+ /** Internal method to filter out duplicate proofs */
26
+ export function ignoreDuplicateProofs(seen = new Set()) {
27
+ return (proof) => {
28
+ const id = getProofUID(proof);
29
+ if (seen.has(id))
30
+ return false;
31
+ else {
32
+ seen.add(id);
33
+ return true;
34
+ }
35
+ };
36
+ }
37
+ /**
38
+ * Returns a decoded cashu token inside an unicode emoji
39
+ * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/ReceiveTokenDialog.vue#L387
40
+ */
41
+ export function decodeTokenFromEmojiString(str) {
42
+ try {
43
+ let decoded = [];
44
+ const chars = Array.from(str);
45
+ if (!chars.length)
46
+ return undefined;
47
+ const fromVariationSelector = function (char) {
48
+ const codePoint = char.codePointAt(0);
49
+ if (codePoint === undefined)
50
+ return null;
51
+ // Handle Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
52
+ if (codePoint >= 0xfe00 && codePoint <= 0xfe0f) {
53
+ // Maps FE00->0, FE01->1, ..., FE0F->15
54
+ const byteValue = codePoint - 0xfe00;
55
+ return String.fromCharCode(byteValue);
56
+ }
57
+ // Handle Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
58
+ if (codePoint >= 0xe0100 && codePoint <= 0xe01ef) {
59
+ // Maps E0100->16, E0101->17, ..., E01EF->255
60
+ const byteValue = codePoint - 0xe0100 + 16;
61
+ return String.fromCharCode(byteValue);
62
+ }
63
+ // No Variation Selector
64
+ return null;
65
+ };
66
+ // Check all input chars for peanut data
67
+ for (const char of chars) {
68
+ let byte = fromVariationSelector(char);
69
+ if (byte === null && decoded.length > 0) {
70
+ break;
71
+ }
72
+ else if (byte === null) {
73
+ continue;
74
+ }
75
+ decoded.push(byte); // got some
76
+ }
77
+ // Switch out token if we found peanut data
78
+ let decodedString = decoded.join("");
79
+ return getDecodedToken(decodedString);
80
+ }
81
+ catch (error) {
82
+ return undefined;
83
+ }
84
+ }
85
+ /**
86
+ * Encodes a token into an emoji char
87
+ * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/SendTokenDialog.vue#L710
88
+ */
89
+ export function encodeTokenToEmoji(token, emoji = "🥜") {
90
+ return (emoji +
91
+ Array.from(typeof token === "string" ? token : getEncodedToken(token))
92
+ .map((char) => {
93
+ const byteValue = char.charCodeAt(0);
94
+ // For byte values 0-15, use Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
95
+ if (byteValue >= 0 && byteValue <= 15) {
96
+ return String.fromCodePoint(0xfe00 + byteValue);
97
+ }
98
+ // For byte values 16-255, use Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
99
+ if (byteValue >= 16 && byteValue <= 255) {
100
+ return String.fromCodePoint(0xe0100 + (byteValue - 16));
101
+ }
102
+ return "";
103
+ })
104
+ .join(""));
105
+ }
@@ -0,0 +1,11 @@
1
+ import { Token } from "@cashu/cashu-ts";
2
+ type ClearMethod = () => void | Promise<void>;
3
+ export interface Couch {
4
+ /** Store a token in the couch */
5
+ store(token: Token): ClearMethod | Promise<ClearMethod>;
6
+ /** Clear all tokens from the couch */
7
+ clear(): void | Promise<void>;
8
+ /** Get all tokens currently stored in the couch */
9
+ getAll(): Token[] | Promise<Token[]>;
10
+ }
11
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,10 @@
1
1
  import { HiddenContentSigner, UnlockedHiddenTags } from "applesauce-core/helpers";
2
- import { NostrEvent } from "applesauce-core/helpers/event";
2
+ import { KnownEvent, NostrEvent } from "applesauce-core/helpers/event";
3
3
  export declare const WALLET_HISTORY_KIND = 7376;
4
+ /** Validated wallet history event */
5
+ export type WalletHistoryEvent = KnownEvent<typeof WALLET_HISTORY_KIND>;
6
+ /** Checks if an event is a valid wallet history event */
7
+ export declare function isValidWalletHistory(event: NostrEvent): event is WalletHistoryEvent;
4
8
  export type HistoryDirection = "in" | "out";
5
9
  export type HistoryContent = {
6
10
  /** The direction of the transaction, in = received, out = sent */
@@ -1,5 +1,9 @@
1
- import { getHiddenTags, isETag, isHiddenTagsUnlocked, lockHiddenTags, notifyEventUpdate, setHiddenTagsEncryptionMethod, unlockHiddenTags, } from "applesauce-core/helpers";
1
+ import { getHiddenTags, hasHiddenTags, isETag, isHiddenTagsUnlocked, lockHiddenTags, notifyEventUpdate, setHiddenTagsEncryptionMethod, unlockHiddenTags, } from "applesauce-core/helpers";
2
2
  export const WALLET_HISTORY_KIND = 7376;
3
+ /** Checks if an event is a valid wallet history event */
4
+ export function isValidWalletHistory(event) {
5
+ return event.kind === WALLET_HISTORY_KIND && hasHiddenTags(event);
6
+ }
3
7
  // Enable hidden content for wallet history kind
4
8
  setHiddenTagsEncryptionMethod(WALLET_HISTORY_KIND, "nip44");
5
9
  export const HistoryContentSymbol = Symbol.for("history-content");
@@ -9,11 +13,16 @@ export function getHistoryRedeemed(history) {
9
13
  }
10
14
  /** Checks if the history contents are locked */
11
15
  export function isHistoryContentUnlocked(history) {
12
- return isHiddenTagsUnlocked(history) && Reflect.has(history, HistoryContentSymbol) === true;
16
+ // Wrap in try catch to avoid throwing validation errors
17
+ try {
18
+ return (HistoryContentSymbol in history || (isHiddenTagsUnlocked(history) && getHistoryContent(history) !== undefined));
19
+ }
20
+ catch { }
21
+ return false;
13
22
  }
14
23
  export function getHistoryContent(history) {
15
24
  // Return cached value if it exists
16
- if (isHistoryContentUnlocked(history))
25
+ if (HistoryContentSymbol in history)
17
26
  return history[HistoryContentSymbol];
18
27
  // Get hidden tags
19
28
  const tags = getHiddenTags(history);
@@ -41,7 +50,7 @@ export function getHistoryContent(history) {
41
50
  /** Decrypts a wallet history event */
42
51
  export async function unlockHistoryContent(history, signer) {
43
52
  // Return cached value if it exists
44
- if (isHistoryContentUnlocked(history))
53
+ if (HistoryContentSymbol in history)
45
54
  return history[HistoryContentSymbol];
46
55
  // Unlock hidden tags if needed
47
56
  await unlockHiddenTags(history, signer);
@@ -2,5 +2,11 @@ export * from "./animated-qr.js";
2
2
  export * from "./history.js";
3
3
  export * from "./tokens.js";
4
4
  export * from "./wallet.js";
5
- export * from "./zap-info.js";
5
+ export * from "./nutzap-info.js";
6
6
  export * from "./nutzap.js";
7
+ export * from "./cashu.js";
8
+ export * from "./couch.js";
9
+ export * from "./local-storage-couch.js";
10
+ export * from "./indexed-db-couch.js";
11
+ export * from "./mint-info.js";
12
+ export * from "./mint-recommendation.js";
@@ -2,5 +2,11 @@ export * from "./animated-qr.js";
2
2
  export * from "./history.js";
3
3
  export * from "./tokens.js";
4
4
  export * from "./wallet.js";
5
- export * from "./zap-info.js";
5
+ export * from "./nutzap-info.js";
6
6
  export * from "./nutzap.js";
7
+ export * from "./cashu.js";
8
+ export * from "./couch.js";
9
+ export * from "./local-storage-couch.js";
10
+ export * from "./indexed-db-couch.js";
11
+ export * from "./mint-info.js";
12
+ export * from "./mint-recommendation.js";
@@ -0,0 +1,34 @@
1
+ import { Token } from "@cashu/cashu-ts";
2
+ import type { Couch } from "./couch.js";
3
+ /**
4
+ * A simple IndexedDB-based implementation of the Couch interface.
5
+ * Stores tokens in the browser's IndexedDB for better performance with larger datasets.
6
+ */
7
+ export declare class IndexedDBCouch implements Couch {
8
+ private dbName;
9
+ private storeName;
10
+ private db;
11
+ private initPromise;
12
+ constructor(dbName?: string, storeName?: string);
13
+ /**
14
+ * Generate a unique ID for each stored token.
15
+ */
16
+ private generateId;
17
+ /**
18
+ * Initialize the IndexedDB database and object store.
19
+ */
20
+ private init;
21
+ /**
22
+ * Store a token in the couch.
23
+ * Returns a function that can be called to remove this specific token.
24
+ */
25
+ store(token: Token): Promise<() => Promise<void>>;
26
+ /**
27
+ * Clear all tokens from the couch.
28
+ */
29
+ clear(): Promise<void>;
30
+ /**
31
+ * Get all tokens currently stored in the couch.
32
+ */
33
+ getAll(): Promise<Token[]>;
34
+ }
@@ -0,0 +1,119 @@
1
+ import { getEncodedToken, getDecodedToken } from "@cashu/cashu-ts";
2
+ const DB_NAME = "applesauce-wallet-couch";
3
+ const STORE_NAME = "tokens";
4
+ const DB_VERSION = 1;
5
+ /**
6
+ * A simple IndexedDB-based implementation of the Couch interface.
7
+ * Stores tokens in the browser's IndexedDB for better performance with larger datasets.
8
+ */
9
+ export class IndexedDBCouch {
10
+ dbName;
11
+ storeName;
12
+ db = null;
13
+ initPromise = null;
14
+ constructor(dbName = DB_NAME, storeName = STORE_NAME) {
15
+ this.dbName = dbName;
16
+ this.storeName = storeName;
17
+ }
18
+ /**
19
+ * Generate a unique ID for each stored token.
20
+ */
21
+ generateId() {
22
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
23
+ }
24
+ /**
25
+ * Initialize the IndexedDB database and object store.
26
+ */
27
+ async init() {
28
+ if (this.db)
29
+ return this.db;
30
+ if (this.initPromise)
31
+ return this.initPromise;
32
+ this.initPromise = new Promise((resolve, reject) => {
33
+ if (typeof window === "undefined" || !window.indexedDB) {
34
+ reject(new Error("IndexedDB is not available"));
35
+ return;
36
+ }
37
+ const request = window.indexedDB.open(this.dbName, DB_VERSION);
38
+ request.onerror = () => reject(request.error);
39
+ request.onsuccess = () => {
40
+ this.db = request.result;
41
+ resolve(this.db);
42
+ };
43
+ request.onupgradeneeded = (event) => {
44
+ const db = event.target.result;
45
+ if (!db.objectStoreNames.contains(this.storeName)) {
46
+ db.createObjectStore(this.storeName, { keyPath: "id" });
47
+ }
48
+ };
49
+ });
50
+ return this.initPromise;
51
+ }
52
+ /**
53
+ * Store a token in the couch.
54
+ * Returns a function that can be called to remove this specific token.
55
+ */
56
+ async store(token) {
57
+ const db = await this.init();
58
+ const id = this.generateId();
59
+ const encodedToken = getEncodedToken(token);
60
+ return new Promise((resolve, reject) => {
61
+ const transaction = db.transaction([this.storeName], "readwrite");
62
+ const store = transaction.objectStore(this.storeName);
63
+ const request = store.add({ id, encodedToken });
64
+ request.onsuccess = () => {
65
+ // Return a function to remove this specific token by ID
66
+ resolve(async () => {
67
+ const removeDb = await this.init();
68
+ const removeTransaction = removeDb.transaction([this.storeName], "readwrite");
69
+ const removeStore = removeTransaction.objectStore(this.storeName);
70
+ const removeRequest = removeStore.delete(id);
71
+ await new Promise((resolve, reject) => {
72
+ removeRequest.onsuccess = () => resolve();
73
+ removeRequest.onerror = () => reject(removeRequest.error);
74
+ });
75
+ });
76
+ };
77
+ request.onerror = () => reject(request.error);
78
+ });
79
+ }
80
+ /**
81
+ * Clear all tokens from the couch.
82
+ */
83
+ async clear() {
84
+ const db = await this.init();
85
+ return new Promise((resolve, reject) => {
86
+ const transaction = db.transaction([this.storeName], "readwrite");
87
+ const store = transaction.objectStore(this.storeName);
88
+ const request = store.clear();
89
+ request.onsuccess = () => resolve();
90
+ request.onerror = () => reject(request.error);
91
+ });
92
+ }
93
+ /**
94
+ * Get all tokens currently stored in the couch.
95
+ */
96
+ async getAll() {
97
+ const db = await this.init();
98
+ return new Promise((resolve, reject) => {
99
+ const transaction = db.transaction([this.storeName], "readonly");
100
+ const store = transaction.objectStore(this.storeName);
101
+ const request = store.getAll();
102
+ request.onsuccess = () => {
103
+ const results = request.result;
104
+ const tokens = results
105
+ .map((item) => {
106
+ try {
107
+ return getDecodedToken(item.encodedToken);
108
+ }
109
+ catch {
110
+ return null;
111
+ }
112
+ })
113
+ .filter((token) => token !== null);
114
+ resolve(tokens);
115
+ };
116
+ request.onerror = () => reject(request.error);
117
+ });
118
+ }
119
+ }
@@ -0,0 +1,29 @@
1
+ import { Token } from "@cashu/cashu-ts";
2
+ import type { Couch } from "./couch.js";
3
+ /**
4
+ * A simple localStorage-based implementation of the Couch interface.
5
+ * Stores tokens in the browser's localStorage.
6
+ */
7
+ export declare class LocalStorageCouch implements Couch {
8
+ private storageKey;
9
+ constructor(storageKey?: string);
10
+ /**
11
+ * Generate a unique ID for each stored token.
12
+ */
13
+ private generateId;
14
+ /**
15
+ * Store a token in the couch.
16
+ * Returns a function that can be called to remove this specific token.
17
+ */
18
+ store(token: Token): () => void;
19
+ /**
20
+ * Clear all tokens from the couch.
21
+ */
22
+ clear(): void;
23
+ /**
24
+ * Get all tokens currently stored in the couch.
25
+ */
26
+ getAll(): Token[];
27
+ private getStoredTokens;
28
+ private saveStoredTokens;
29
+ }
@@ -0,0 +1,78 @@
1
+ import { getEncodedToken, getDecodedToken } from "@cashu/cashu-ts";
2
+ const STORAGE_KEY = "applesauce:couch:tokens";
3
+ /**
4
+ * A simple localStorage-based implementation of the Couch interface.
5
+ * Stores tokens in the browser's localStorage.
6
+ */
7
+ export class LocalStorageCouch {
8
+ storageKey;
9
+ constructor(storageKey = STORAGE_KEY) {
10
+ this.storageKey = storageKey;
11
+ }
12
+ /**
13
+ * Generate a unique ID for each stored token.
14
+ */
15
+ generateId() {
16
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
17
+ }
18
+ /**
19
+ * Store a token in the couch.
20
+ * Returns a function that can be called to remove this specific token.
21
+ */
22
+ store(token) {
23
+ const id = this.generateId();
24
+ const encodedToken = getEncodedToken(token);
25
+ const stored = this.getStoredTokens();
26
+ stored.push({ id, encodedToken });
27
+ this.saveStoredTokens(stored);
28
+ // Return a function to remove this specific token by ID
29
+ return () => {
30
+ const currentStored = this.getStoredTokens();
31
+ const filtered = currentStored.filter((item) => item.id !== id);
32
+ this.saveStoredTokens(filtered);
33
+ };
34
+ }
35
+ /**
36
+ * Clear all tokens from the couch.
37
+ */
38
+ clear() {
39
+ if (typeof window !== "undefined" && window.localStorage) {
40
+ window.localStorage.removeItem(this.storageKey);
41
+ }
42
+ }
43
+ /**
44
+ * Get all tokens currently stored in the couch.
45
+ */
46
+ getAll() {
47
+ const stored = this.getStoredTokens();
48
+ return stored
49
+ .map((item) => {
50
+ try {
51
+ return getDecodedToken(item.encodedToken);
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ })
57
+ .filter((token) => token !== null);
58
+ }
59
+ getStoredTokens() {
60
+ if (typeof window === "undefined" || !window.localStorage) {
61
+ return [];
62
+ }
63
+ try {
64
+ const stored = window.localStorage.getItem(this.storageKey);
65
+ if (!stored)
66
+ return [];
67
+ return JSON.parse(stored);
68
+ }
69
+ catch {
70
+ return [];
71
+ }
72
+ }
73
+ saveStoredTokens(tokens) {
74
+ if (typeof window !== "undefined" && window.localStorage) {
75
+ window.localStorage.setItem(this.storageKey, JSON.stringify(tokens));
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,40 @@
1
+ import { KnownEvent } from "applesauce-core/helpers";
2
+ import { NostrEvent } from "applesauce-core/helpers/event";
3
+ export declare const CASHU_MINT_INFO_KIND = 38172;
4
+ export type CashuMintInfoEvent = KnownEvent<typeof CASHU_MINT_INFO_KIND>;
5
+ export type NetworkType = "mainnet" | "testnet" | "signet" | "regtest";
6
+ export declare const CashuMintPubkeySymbol: unique symbol;
7
+ export declare const CashuMintURLSymbol: unique symbol;
8
+ export declare const CashuMintNutsSymbol: unique symbol;
9
+ export declare const CashuMintNetworkSymbol: unique symbol;
10
+ /**
11
+ * Returns the mint's pubkey from a kind:38172 cashu mint info event
12
+ * This is found in the `d` tag and is the pubkey from the mint's `/v1/info` endpoint
13
+ */
14
+ export declare function getCashuMintPubkey(event: NostrEvent): string | undefined;
15
+ /**
16
+ * Returns the mint URL from a kind:38172 cashu mint info event
17
+ * This is the URL to the cashu mint (from the `u` tag)
18
+ */
19
+ export declare function getCashuMintURL(event: CashuMintInfoEvent): string;
20
+ export declare function getCashuMintURL(event: NostrEvent): string | undefined;
21
+ /**
22
+ * Returns the supported nuts from a kind:38172 cashu mint info event
23
+ * This is a comma-separated list of nut numbers (e.g., "1,2,3,4,5,6,7")
24
+ */
25
+ export declare function getCashuMintNuts(event: NostrEvent): number[];
26
+ /**
27
+ * Returns the network type from a kind:38172 cashu mint info event
28
+ * Should be one of: mainnet, testnet, signet, or regtest
29
+ */
30
+ export declare function getCashuMintNetwork(event: NostrEvent): NetworkType | undefined;
31
+ /**
32
+ * Returns the optional metadata content from a kind:38172 cashu mint info event
33
+ * This is a kind:0-style metadata JSON object, useful when the pubkey is not a normal user
34
+ */
35
+ export declare function getCashuMintMetadata(event: NostrEvent): Record<string, any> | undefined;
36
+ /**
37
+ * Validates that an event is a proper kind:38172 cashu mint info event
38
+ * Checks that the event is kind 38172 and has the required `d` and `u` tags
39
+ */
40
+ export declare function isValidCashuMintInfo(event?: NostrEvent): event is CashuMintInfoEvent;
@@ -0,0 +1,80 @@
1
+ import { getOrComputeCachedValue, getTagValue, isHex, safeParse } from "applesauce-core/helpers";
2
+ import { getReplaceableIdentifier } from "applesauce-core/helpers/event";
3
+ // NIP-87 Cashu Mint Information Event Kind
4
+ export const CASHU_MINT_INFO_KIND = 38172;
5
+ // Symbols for caching computed values
6
+ export const CashuMintPubkeySymbol = Symbol.for("cashu-mint-pubkey");
7
+ export const CashuMintURLSymbol = Symbol.for("cashu-mint-url");
8
+ export const CashuMintNutsSymbol = Symbol.for("cashu-mint-nuts");
9
+ export const CashuMintNetworkSymbol = Symbol.for("cashu-mint-network");
10
+ // ============================================================================
11
+ // Cashu Mint Information Event (kind:38172) Helpers
12
+ // ============================================================================
13
+ /**
14
+ * Returns the mint's pubkey from a kind:38172 cashu mint info event
15
+ * This is found in the `d` tag and is the pubkey from the mint's `/v1/info` endpoint
16
+ */
17
+ export function getCashuMintPubkey(event) {
18
+ return getOrComputeCachedValue(event, CashuMintPubkeySymbol, () => {
19
+ const identifier = getReplaceableIdentifier(event);
20
+ // Only return hex pubkeys
21
+ if (!isHex(identifier))
22
+ return undefined;
23
+ return identifier || undefined;
24
+ });
25
+ }
26
+ export function getCashuMintURL(event) {
27
+ return getOrComputeCachedValue(event, CashuMintURLSymbol, () => {
28
+ const url = getTagValue(event, "u");
29
+ return url && URL.canParse(url) ? url : undefined;
30
+ });
31
+ }
32
+ /**
33
+ * Returns the supported nuts from a kind:38172 cashu mint info event
34
+ * This is a comma-separated list of nut numbers (e.g., "1,2,3,4,5,6,7")
35
+ */
36
+ export function getCashuMintNuts(event) {
37
+ return getOrComputeCachedValue(event, CashuMintNutsSymbol, () => {
38
+ const nutsStr = getTagValue(event, "nuts");
39
+ if (!nutsStr)
40
+ return [];
41
+ return nutsStr
42
+ .split(",")
43
+ .map((n) => parseInt(n.trim(), 10))
44
+ .filter((n) => !isNaN(n));
45
+ });
46
+ }
47
+ /**
48
+ * Returns the network type from a kind:38172 cashu mint info event
49
+ * Should be one of: mainnet, testnet, signet, or regtest
50
+ */
51
+ export function getCashuMintNetwork(event) {
52
+ return getOrComputeCachedValue(event, CashuMintNetworkSymbol, () => {
53
+ const network = getTagValue(event, "n");
54
+ if (!network)
55
+ return undefined;
56
+ const validNetworks = ["mainnet", "testnet", "signet", "regtest"];
57
+ return validNetworks.includes(network) ? network : undefined;
58
+ });
59
+ }
60
+ /**
61
+ * Returns the optional metadata content from a kind:38172 cashu mint info event
62
+ * This is a kind:0-style metadata JSON object, useful when the pubkey is not a normal user
63
+ */
64
+ export function getCashuMintMetadata(event) {
65
+ if (!event.content)
66
+ return undefined;
67
+ return safeParse(event.content);
68
+ }
69
+ /**
70
+ * Validates that an event is a proper kind:38172 cashu mint info event
71
+ * Checks that the event is kind 38172 and has the required `d` and `u` tags
72
+ */
73
+ export function isValidCashuMintInfo(event) {
74
+ if (!event)
75
+ return false;
76
+ if (event.kind !== CASHU_MINT_INFO_KIND)
77
+ return false;
78
+ const url = getCashuMintURL(event);
79
+ return url !== undefined;
80
+ }
@@ -0,0 +1,41 @@
1
+ import { KnownEvent } from "applesauce-core/helpers";
2
+ import { NostrEvent } from "applesauce-core/helpers/event";
3
+ import { AddressPointer } from "applesauce-core/helpers/pointers";
4
+ export declare const MINT_RECOMMENDATION_KIND = 38000;
5
+ export type MintRecommendationEvent = KnownEvent<typeof MINT_RECOMMENDATION_KIND>;
6
+ export declare const RecommendationKindSymbol: unique symbol;
7
+ export declare const RecommendationURLSymbol: unique symbol;
8
+ export declare const RecommendationAddressPointerSymbol: unique symbol;
9
+ /**
10
+ * Returns the recommended event kind from a kind:38000 recommendation event
11
+ * This should be 38172 for cashu mints
12
+ */
13
+ export declare function getRecommendationKind(event: MintRecommendationEvent): number;
14
+ export declare function getRecommendationKind(event: NostrEvent): number | undefined;
15
+ /**
16
+ * Returns the d-identifier from a kind:38000 recommendation event
17
+ * This is the kind:38172 event identifier this event is recommending
18
+ */
19
+ export declare function getRecommendationMintPubkey(event: NostrEvent): string | undefined;
20
+ /**
21
+ * Returns the URL from a kind:38000 recommendation event
22
+ * This is an optional `u` tag that provides a recommended way to connect to the cashu mint
23
+ * Each recommendation event recommends a single mint, so there is at most one `u` tag
24
+ */
25
+ export declare function getRecommendationURL(event: MintRecommendationEvent): string | undefined;
26
+ export declare function getRecommendationURL(event: NostrEvent): string | undefined;
27
+ /**
28
+ * Returns the address pointer from a kind:38000 recommendation event
29
+ * This `a` tag points to the kind:38172 event of the cashu mint
30
+ * The first value is the event identifier, the second value is a relay hint
31
+ * Each recommendation event recommends a single mint, so there is at most one `a` tag
32
+ */
33
+ export declare function getRecommendationAddressPointer(event: MintRecommendationEvent): AddressPointer | undefined;
34
+ export declare function getRecommendationAddressPointer(event: NostrEvent): AddressPointer | undefined;
35
+ /**
36
+ * Validates that an event is a proper kind:38000 recommendation event
37
+ * Checks that the event is kind 38000, has the required `k` and `d` tags,
38
+ * and that the `k` tag is 38172 (cashu mint kind)
39
+ * Each recommendation event recommends a single cashu mint
40
+ */
41
+ export declare function isValidMintRecommendation(event?: NostrEvent): event is MintRecommendationEvent;