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

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 (75) 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/types.d.ts +5 -0
  11. package/dist/wallet-connect.d.ts +28 -11
  12. package/dist/wallet-connect.js +90 -30
  13. package/dist/wallet-service.d.ts +20 -5
  14. package/dist/wallet-service.js +35 -12
  15. package/package.json +3 -3
  16. package/dist/actions/index.d.ts +0 -1
  17. package/dist/actions/index.js +0 -1
  18. package/dist/actions/tokens.d.ts +0 -17
  19. package/dist/actions/tokens.js +0 -110
  20. package/dist/actions/wallet.d.ts +0 -13
  21. package/dist/actions/wallet.js +0 -64
  22. package/dist/actions/zap-info.d.ts +0 -22
  23. package/dist/actions/zap-info.js +0 -83
  24. package/dist/actions/zaps.d.ts +0 -8
  25. package/dist/actions/zaps.js +0 -30
  26. package/dist/blueprints/history.d.ts +0 -4
  27. package/dist/blueprints/history.js +0 -11
  28. package/dist/blueprints/info.d.ts +0 -4
  29. package/dist/blueprints/info.js +0 -8
  30. package/dist/blueprints/tokens.d.ts +0 -7
  31. package/dist/blueprints/tokens.js +0 -11
  32. package/dist/blueprints/wallet.d.ts +0 -5
  33. package/dist/blueprints/wallet.js +0 -11
  34. package/dist/blueprints/zaps.d.ts +0 -8
  35. package/dist/blueprints/zaps.js +0 -12
  36. package/dist/helpers/animated-qr.d.ts +0 -30
  37. package/dist/helpers/animated-qr.js +0 -71
  38. package/dist/helpers/history.d.ts +0 -26
  39. package/dist/helpers/history.js +0 -47
  40. package/dist/helpers/info.d.ts +0 -34
  41. package/dist/helpers/info.js +0 -97
  42. package/dist/helpers/methods.d.ts +0 -1
  43. package/dist/helpers/methods.js +0 -1
  44. package/dist/helpers/nutzap.d.ts +0 -27
  45. package/dist/helpers/nutzap.js +0 -66
  46. package/dist/helpers/tokens.d.ts +0 -58
  47. package/dist/helpers/tokens.js +0 -162
  48. package/dist/helpers/wallet.d.ts +0 -15
  49. package/dist/helpers/wallet.js +0 -41
  50. package/dist/helpers/zap-info.d.ts +0 -19
  51. package/dist/helpers/zap-info.js +0 -42
  52. package/dist/interface.d.ts +0 -6
  53. package/dist/interface.js +0 -1
  54. package/dist/models/history.d.ts +0 -6
  55. package/dist/models/history.js +0 -21
  56. package/dist/models/index.d.ts +0 -4
  57. package/dist/models/index.js +0 -4
  58. package/dist/models/nutzap.d.ts +0 -6
  59. package/dist/models/nutzap.js +0 -16
  60. package/dist/models/tokens.d.ts +0 -6
  61. package/dist/models/tokens.js +0 -58
  62. package/dist/models/wallet.d.ts +0 -13
  63. package/dist/models/wallet.js +0 -18
  64. package/dist/operations/history.d.ts +0 -7
  65. package/dist/operations/history.js +0 -34
  66. package/dist/operations/index.d.ts +0 -5
  67. package/dist/operations/index.js +0 -5
  68. package/dist/operations/nutzap.d.ts +0 -14
  69. package/dist/operations/nutzap.js +0 -33
  70. package/dist/operations/tokens.d.ts +0 -4
  71. package/dist/operations/tokens.js +0 -24
  72. package/dist/operations/wallet.d.ts +0 -8
  73. package/dist/operations/wallet.js +0 -30
  74. package/dist/operations/zap-info.d.ts +0 -10
  75. package/dist/operations/zap-info.js +0 -17
@@ -1,71 +0,0 @@
1
- import { getEncodedTokenV4 } from "@cashu/cashu-ts";
2
- import { UR, URDecoder, UREncoder } from "@gandlaf21/bc-ur/dist/lib/es6/index.js";
3
- import { defer, filter, interval, map, Observable, shareReplay } from "rxjs";
4
- /** Preset speeds for the animated qr code */
5
- export const ANIMATED_QR_INTERVAL = {
6
- SLOW: 500,
7
- MEDIUM: 250,
8
- FAST: 150,
9
- };
10
- /** Presets for fragment length for animated qr code */
11
- export const ANIMATED_QR_FRAGMENTS = {
12
- SHORT: 50,
13
- MEDIUM: 100,
14
- LONG: 150,
15
- };
16
- /** Creates an observable that iterates through a multi-part animated qr code */
17
- export function sendAnimated(token, options) {
18
- // start the stream as soon as there is subscriber
19
- return defer(() => {
20
- let str = typeof token === "string" ? token : getEncodedTokenV4(token);
21
- let utf8 = new TextEncoder();
22
- let buffer = utf8.encode(str);
23
- let ur = UR.from(buffer);
24
- let encoder = new UREncoder(ur, options?.fragmentLength ?? 100, 0);
25
- return interval(options?.interval ?? ANIMATED_QR_INTERVAL.FAST).pipe(map(() => encoder.nextPart()));
26
- });
27
- }
28
- /** An operator that decodes UR, emits progress percent and completes with final result or error */
29
- function urDecoder() {
30
- return (source) => new Observable((observer) => {
31
- const decoder = new URDecoder();
32
- return source.subscribe((part) => {
33
- decoder.receivePart(part);
34
- if (decoder.isComplete() && decoder.isSuccess()) {
35
- // emit progress
36
- const progress = decoder.estimatedPercentComplete();
37
- observer.next(progress);
38
- // emit result
39
- const ur = decoder.resultUR();
40
- const decoded = ur.decodeCBOR();
41
- const utf8 = new TextDecoder();
42
- const tokenStr = utf8.decode(decoded);
43
- observer.next(tokenStr);
44
- // complete
45
- observer.complete();
46
- }
47
- else if (decoder.isError()) {
48
- // emit error
49
- const reason = decoder.resultError();
50
- observer.error(new Error(reason));
51
- }
52
- else {
53
- // emit progress
54
- const progress = decoder.estimatedPercentComplete();
55
- observer.next(progress);
56
- }
57
- });
58
- });
59
- }
60
- /** Creates an observable that completes with decoded token */
61
- export function receiveAnimated(input) {
62
- return input.pipe(
63
- // convert to lower case
64
- map((str) => str.toLowerCase()),
65
- // filter out non UR parts
66
- filter((str) => str.startsWith("ur:bytes")),
67
- // decode UR and complete
68
- urDecoder(),
69
- // only run one decoder
70
- shareReplay(1));
71
- }
@@ -1,26 +0,0 @@
1
- import { HiddenContentSigner } from "applesauce-core/helpers";
2
- import { NostrEvent } from "nostr-tools";
3
- export declare const WALLET_HISTORY_KIND = 7376;
4
- export type HistoryDirection = "in" | "out";
5
- export type HistoryContent = {
6
- /** The direction of the transaction, in = received, out = sent */
7
- direction: HistoryDirection;
8
- /** The amount of the transaction */
9
- amount: number;
10
- /** An array of token event ids created */
11
- created: string[];
12
- /** The mint that was spent from */
13
- mint?: string;
14
- /** The fee paid */
15
- fee?: number;
16
- };
17
- export declare const HistoryContentSymbol: unique symbol;
18
- /** returns an array of redeemed event ids in a history event */
19
- export declare function getHistoryRedeemed(history: NostrEvent): string[];
20
- /** Checks if the history contents are locked */
21
- export declare function isHistoryContentLocked(history: NostrEvent): boolean;
22
- /** Returns the parsed content of a 7376 history event */
23
- export declare function getHistoryContent(history: NostrEvent): HistoryContent | undefined;
24
- /** Decrypts a wallet history event */
25
- export declare function unlockHistoryContent(history: NostrEvent, signer: HiddenContentSigner): Promise<HistoryContent>;
26
- export declare function lockHistoryContent(history: NostrEvent): void;
@@ -1,47 +0,0 @@
1
- import { getHiddenTags, getOrComputeCachedValue, isETag, isHiddenContentLocked, isHiddenTagsLocked, lockHiddenTags, setHiddenTagsEncryptionMethod, unlockHiddenTags, } from "applesauce-core/helpers";
2
- export const WALLET_HISTORY_KIND = 7376;
3
- // Enable hidden content for wallet history kind
4
- setHiddenTagsEncryptionMethod(WALLET_HISTORY_KIND, "nip44");
5
- export const HistoryContentSymbol = Symbol.for("history-content");
6
- /** returns an array of redeemed event ids in a history event */
7
- export function getHistoryRedeemed(history) {
8
- return history.tags.filter((t) => isETag(t) && t[3] === "redeemed").map((t) => t[1]);
9
- }
10
- /** Checks if the history contents are locked */
11
- export function isHistoryContentLocked(history) {
12
- return isHiddenTagsLocked(history);
13
- }
14
- /** Returns the parsed content of a 7376 history event */
15
- export function getHistoryContent(history) {
16
- if (isHistoryContentLocked(history))
17
- return undefined;
18
- return getOrComputeCachedValue(history, HistoryContentSymbol, () => {
19
- const tags = getHiddenTags(history);
20
- if (!tags)
21
- throw new Error("History event is locked");
22
- const direction = tags.find((t) => t[0] === "direction")?.[1];
23
- if (!direction)
24
- throw new Error("History event missing direction");
25
- const amountStr = tags.find((t) => t[0] === "amount")?.[1];
26
- if (!amountStr)
27
- throw new Error("History event missing amount");
28
- const amount = parseInt(amountStr);
29
- if (!Number.isFinite(amount))
30
- throw new Error("Failed to parse amount");
31
- const mint = tags.find((t) => t[0] === "mint")?.[1];
32
- const feeStr = tags.find((t) => t[0] === "fee")?.[1];
33
- const fee = feeStr ? parseInt(feeStr) : undefined;
34
- const created = tags.filter((t) => isETag(t) && t[3] === "created").map((t) => t[1]);
35
- return { direction, amount, created, mint, fee };
36
- });
37
- }
38
- /** Decrypts a wallet history event */
39
- export async function unlockHistoryContent(history, signer) {
40
- if (isHiddenContentLocked(history))
41
- await unlockHiddenTags(history, signer);
42
- return getHistoryContent(history);
43
- }
44
- export function lockHistoryContent(history) {
45
- Reflect.deleteProperty(history, HistoryContentSymbol);
46
- lockHiddenTags(history);
47
- }
@@ -1,34 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { EncryptionMethods } from "./encryption.js";
3
- import { WalletMethods } from "./methods.js";
4
- import { NotificationTypes } from "./notification.js";
5
- export declare const WALLET_INFO_KIND = 13194;
6
- /** A symbol used to cache the wallet info on the event */
7
- export declare const WalletInfoSymbol: unique symbol;
8
- /** Wallet service capabilities and information */
9
- export interface WalletFeatures {
10
- /** List of supported methods for this wallet service */
11
- methods: WalletMethods[];
12
- /** List of supported encryption methods */
13
- encryption: EncryptionMethods[];
14
- /** List of supported notifications, optional */
15
- notifications?: NotificationTypes[];
16
- }
17
- /** Gets the wallet info from a kind 13194 event */
18
- export declare function getWalletFeatures(info: NostrEvent): WalletFeatures | null;
19
- /** Gets the encryption methods from a wallet info event */
20
- export declare function getEncryptionMethods(info: NostrEvent | WalletFeatures): EncryptionMethods[];
21
- /** Checks if the wallet service supports a specific encryption method */
22
- export declare function supportsEncryption(info: NostrEvent | WalletFeatures, encryption: EncryptionMethods): boolean;
23
- /** Gets the preferred encryption method (nip44_v2 preferred over nip04) */
24
- export declare function getPreferredEncryption(info: NostrEvent | WalletFeatures): EncryptionMethods;
25
- /** Checks if the wallet service supports a specific method */
26
- export declare function supportsMethod(info: NostrEvent | WalletFeatures, method: WalletMethods): boolean;
27
- /** Checks if the wallet service supports notifications */
28
- export declare function supportsNotifications(info: NostrEvent | WalletFeatures): boolean;
29
- /** Checks if the wallet service supports a specific notification type */
30
- export declare function supportsNotificationType(info: NostrEvent | WalletFeatures, notificationType: NotificationTypes): boolean;
31
- /** Gets all supported methods from the wallet info */
32
- export declare function getSupportedMethods(info: NostrEvent | WalletFeatures): WalletMethods[];
33
- /** Gets all supported notifications from the wallet info */
34
- export declare function getSupportedNotifications(info: NostrEvent | WalletFeatures): NotificationTypes[];
@@ -1,97 +0,0 @@
1
- import { getOrComputeCachedValue, getTagValue, isEvent } from "applesauce-core/helpers";
2
- export const WALLET_INFO_KIND = 13194;
3
- /** A symbol used to cache the wallet info on the event */
4
- export const WalletInfoSymbol = Symbol("wallet-info");
5
- /** Gets the wallet info from a kind 13194 event */
6
- export function getWalletFeatures(info) {
7
- if (info.kind !== WALLET_INFO_KIND)
8
- return null;
9
- return getOrComputeCachedValue(info, WalletInfoSymbol, () => {
10
- const content = info.content.trim();
11
- if (!content)
12
- return null;
13
- // Parse methods from content (space-separated)
14
- const contentParts = content.split(/\s+/);
15
- const methods = contentParts
16
- .filter((part) => [
17
- "pay_invoice",
18
- "multi_pay_invoice",
19
- "pay_keysend",
20
- "multi_pay_keysend",
21
- "make_invoice",
22
- "lookup_invoice",
23
- "list_transactions",
24
- "get_balance",
25
- "get_info",
26
- "notifications",
27
- ].includes(part))
28
- .filter((part) => part !== "notifications");
29
- // Parse encryption methods from encryption tag
30
- const encryptionTag = getTagValue(info, "encryption");
31
- const encryption = encryptionTag
32
- ? encryptionTag
33
- .split(/\s+/)
34
- .filter((method) => method === "nip44_v2" || method === "nip04")
35
- : ["nip04"]; // Default to nip04 if no encryption tag is present
36
- // Parse notifications from notifications tag
37
- const notificationsTag = getTagValue(info, "notifications");
38
- const notifications = notificationsTag
39
- ? notificationsTag
40
- .split(/\s+/)
41
- .filter((notif) => notif === "payment_received" || notif === "payment_sent")
42
- : undefined;
43
- return {
44
- methods,
45
- encryption,
46
- notifications,
47
- };
48
- });
49
- }
50
- /** Gets the encryption methods from a wallet info event */
51
- export function getEncryptionMethods(info) {
52
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
53
- return walletInfo?.encryption ?? [];
54
- }
55
- /** Checks if the wallet service supports a specific encryption method */
56
- export function supportsEncryption(info, encryption) {
57
- const encryptionMethods = getEncryptionMethods(info);
58
- return encryptionMethods.includes(encryption);
59
- }
60
- /** Gets the preferred encryption method (nip44_v2 preferred over nip04) */
61
- export function getPreferredEncryption(info) {
62
- const encryptionMethods = getEncryptionMethods(info);
63
- if (encryptionMethods.length === 0)
64
- return "nip04";
65
- // Prefer nip44_v2 over nip04
66
- if (encryptionMethods.includes("nip44_v2"))
67
- return "nip44_v2";
68
- if (encryptionMethods.includes("nip04"))
69
- return "nip04";
70
- // Absence of this tag implies that the wallet only supports nip04.
71
- return "nip04";
72
- }
73
- /** Checks if the wallet service supports a specific method */
74
- export function supportsMethod(info, method) {
75
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
76
- return walletInfo?.methods.includes(method) ?? false;
77
- }
78
- /** Checks if the wallet service supports notifications */
79
- export function supportsNotifications(info) {
80
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
81
- return (walletInfo?.notifications?.length ?? 0) > 0;
82
- }
83
- /** Checks if the wallet service supports a specific notification type */
84
- export function supportsNotificationType(info, notificationType) {
85
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
86
- return walletInfo?.notifications?.includes(notificationType) ?? false;
87
- }
88
- /** Gets all supported methods from the wallet info */
89
- export function getSupportedMethods(info) {
90
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
91
- return walletInfo?.methods ?? [];
92
- }
93
- /** Gets all supported notifications from the wallet info */
94
- export function getSupportedNotifications(info) {
95
- const walletInfo = isEvent(info) ? getWalletFeatures(info) : info;
96
- return walletInfo?.notifications ?? [];
97
- }
@@ -1 +0,0 @@
1
- export type WalletMethods = "pay_invoice" | "multi_pay_invoice" | "pay_keysend" | "multi_pay_keysend" | "make_invoice" | "lookup_invoice" | "list_transactions" | "get_balance" | "get_info";
@@ -1 +0,0 @@
1
- export {};
@@ -1,27 +0,0 @@
1
- import { Proof } from "@cashu/cashu-ts";
2
- import { NostrEvent } from "nostr-tools";
3
- import { AddressPointer, EventPointer } from "nostr-tools/nip19";
4
- export declare const NUTZAP_KIND = 9321;
5
- export declare const NutzapProofsSymbol: unique symbol;
6
- export declare const NutzapAmountSymbol: unique symbol;
7
- export declare const NutzapMintSymbol: unique symbol;
8
- /** Returns the cashu proofs from a kind:9321 nutzap event */
9
- export declare function getNutzapProofs(event: NostrEvent): Proof[];
10
- /** Returns the mint URL from a kind:9321 nutzap event */
11
- export declare function getNutzapMint(event: NostrEvent): string | undefined;
12
- /** Returns the recipient pubkey from a kind:9321 nutzap event */
13
- export declare function getNutzapRecipient(event: NostrEvent): string | undefined;
14
- /** Returns the event ID being nutzapped from a kind:9321 nutzap event */
15
- export declare function getNutzapEventPointer(event: NostrEvent): EventPointer | undefined;
16
- /** Returns the event ID being nutzapped from a kind:9321 nutzap event */
17
- export declare function getNutzapAddressPointer(event: NostrEvent): AddressPointer | undefined;
18
- /** Returns the EventPointer or AddressPointer from a kind:9321 nutzap event */
19
- export declare function getNutzapPointer(event: NostrEvent): EventPointer | AddressPointer | undefined;
20
- /** Returns the comment from a kind:9321 nutzap event */
21
- export declare function getNutzapComment(event: NostrEvent): string | undefined;
22
- /** Calculates the total amount of sats in a kind:9321 nutzap event */
23
- export declare function getNutzapAmount(event: NostrEvent): number;
24
- /** Checks if a nutzap is valid according to NIP-61 requirements */
25
- export declare function isValidNutzap(nutzap: NostrEvent): boolean;
26
- /** Checks if a nutzap event has already been redeemed based on kind:7376 wallet history events */
27
- export declare function isNutzapRedeemed(nutzapId: string, history: NostrEvent[]): boolean;
@@ -1,66 +0,0 @@
1
- import { getAddressPointerFromATag, getEventPointerFromETag, getOrComputeCachedValue, getTagValue, processTags, safeParse, } from "applesauce-core/helpers";
2
- import { getHistoryRedeemed } from "./history.js";
3
- export const NUTZAP_KIND = 9321;
4
- // Symbols for caching computed values
5
- export const NutzapProofsSymbol = Symbol.for("nutzap-proofs");
6
- export const NutzapAmountSymbol = Symbol.for("nutzap-amount");
7
- export const NutzapMintSymbol = Symbol.for("nutzap-mint");
8
- /** Returns the cashu proofs from a kind:9321 nutzap event */
9
- export function getNutzapProofs(event) {
10
- return getOrComputeCachedValue(event, NutzapProofsSymbol, () => {
11
- return processTags(event.tags, (tag) => (tag[0] === "proof" ? safeParse(tag[1]) : undefined));
12
- });
13
- }
14
- /** Returns the mint URL from a kind:9321 nutzap event */
15
- export function getNutzapMint(event) {
16
- return getOrComputeCachedValue(event, NutzapMintSymbol, () => {
17
- const url = getTagValue(event, "u");
18
- return url && URL.canParse(url) ? url : undefined;
19
- });
20
- }
21
- /** Returns the recipient pubkey from a kind:9321 nutzap event */
22
- export function getNutzapRecipient(event) {
23
- return getTagValue(event, "p");
24
- }
25
- /** Returns the event ID being nutzapped from a kind:9321 nutzap event */
26
- export function getNutzapEventPointer(event) {
27
- const tag = event.tags.find((t) => t[0] === "e");
28
- if (!tag)
29
- return;
30
- return getEventPointerFromETag(tag);
31
- }
32
- /** Returns the event ID being nutzapped from a kind:9321 nutzap event */
33
- export function getNutzapAddressPointer(event) {
34
- const tag = event.tags.find((t) => t[0] === "a");
35
- if (!tag)
36
- return;
37
- return getAddressPointerFromATag(tag);
38
- }
39
- /** Returns the EventPointer or AddressPointer from a kind:9321 nutzap event */
40
- export function getNutzapPointer(event) {
41
- return getNutzapEventPointer(event) ?? getNutzapAddressPointer(event);
42
- }
43
- /** Returns the comment from a kind:9321 nutzap event */
44
- export function getNutzapComment(event) {
45
- return event.content || undefined;
46
- }
47
- /** Calculates the total amount of sats in a kind:9321 nutzap event */
48
- export function getNutzapAmount(event) {
49
- return getOrComputeCachedValue(event, NutzapAmountSymbol, () => {
50
- const proofs = getNutzapProofs(event);
51
- return proofs.reduce((total, proof) => total + (proof.amount || 0), 0);
52
- });
53
- }
54
- /** Checks if a nutzap is valid according to NIP-61 requirements */
55
- export function isValidNutzap(nutzap) {
56
- const mint = getNutzapMint(nutzap);
57
- const recipient = getNutzapRecipient(nutzap);
58
- const proofs = getNutzapProofs(nutzap);
59
- if (!mint || !recipient || proofs.length === 0)
60
- return false;
61
- return true;
62
- }
63
- /** Checks if a nutzap event has already been redeemed based on kind:7376 wallet history events */
64
- export function isNutzapRedeemed(nutzapId, history) {
65
- return history.some((entry) => getHistoryRedeemed(entry).includes(nutzapId));
66
- }
@@ -1,58 +0,0 @@
1
- import { Proof, Token } from "@cashu/cashu-ts";
2
- import { HiddenContentSigner } from "applesauce-core/helpers";
3
- import { NostrEvent } from "nostr-tools";
4
- export declare const WALLET_TOKEN_KIND = 7375;
5
- /** Internal method for creating a unique id for each proof */
6
- export declare function getProofUID(proof: Proof): string;
7
- /** Internal method to filter out duplicate proofs */
8
- export declare function ignoreDuplicateProofs(seen?: Set<string>): (proof: Proof) => boolean;
9
- export type TokenContent = {
10
- /** Cashu mint for the proofs */
11
- mint: string;
12
- /** Cashu proofs */
13
- proofs: {
14
- amount: number;
15
- secret: string;
16
- C: string;
17
- id: string;
18
- }[];
19
- /** The cashu unit */
20
- unit?: string;
21
- /** tokens that were destroyed in the creation of this token (helps on wallet state transitions) */
22
- del: string[];
23
- };
24
- export declare const TokenContentSymbol: unique symbol;
25
- /**
26
- * Returns the decrypted and parsed details of a 7375 token event
27
- * @throws
28
- */
29
- export declare function getTokenContent(token: NostrEvent): TokenContent | undefined;
30
- /** Returns if token details are locked */
31
- export declare function isTokenContentLocked(token: NostrEvent): boolean;
32
- /** Decrypts a k:7375 token event */
33
- export declare function unlockTokenContent(token: NostrEvent, signer: HiddenContentSigner): Promise<TokenContent>;
34
- /** Removes the unencrypted hidden content */
35
- export declare function lockTokenContent(token: NostrEvent): void;
36
- /**
37
- * Gets the totaled amount of proofs in a token event
38
- * @param token The token event to calculate the total
39
- */
40
- export declare function getTokenProofsTotal(token: NostrEvent): number | undefined;
41
- /**
42
- * Selects oldest tokens and proofs that total up to more than the min amount
43
- * @throws
44
- */
45
- export declare function dumbTokenSelection(tokens: NostrEvent[], minAmount: number, mint?: string): {
46
- events: NostrEvent[];
47
- proofs: Proof[];
48
- };
49
- /**
50
- * Returns a decoded cashu token inside an unicode emoji
51
- * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/ReceiveTokenDialog.vue#L387
52
- */
53
- export declare function decodeTokenFromEmojiString(str: string): Token | undefined;
54
- /**
55
- * Encodes a token into an emoji char
56
- * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/SendTokenDialog.vue#L710
57
- */
58
- export declare function encodeTokenToEmoji(token: Token | string, emoji?: string): string;
@@ -1,162 +0,0 @@
1
- import { getDecodedToken, getEncodedToken } from "@cashu/cashu-ts";
2
- import { getHiddenContent, getOrComputeCachedValue, isHiddenContentLocked, isHiddenTagsLocked, lockHiddenContent, setHiddenContentEncryptionMethod, unlockHiddenContent, } from "applesauce-core/helpers";
3
- export const WALLET_TOKEN_KIND = 7375;
4
- // Enable hidden content for wallet token kind
5
- setHiddenContentEncryptionMethod(WALLET_TOKEN_KIND, "nip44");
6
- /** Internal method for creating a unique id for each proof */
7
- export function getProofUID(proof) {
8
- return proof.id + proof.amount + proof.C + proof.secret;
9
- }
10
- /** Internal method to filter out duplicate proofs */
11
- export function ignoreDuplicateProofs(seen = new Set()) {
12
- return (proof) => {
13
- const id = getProofUID(proof);
14
- if (seen.has(id))
15
- return false;
16
- else {
17
- seen.add(id);
18
- return true;
19
- }
20
- };
21
- }
22
- export const TokenContentSymbol = Symbol.for("token-content");
23
- /**
24
- * Returns the decrypted and parsed details of a 7375 token event
25
- * @throws
26
- */
27
- export function getTokenContent(token) {
28
- if (isHiddenTagsLocked(token))
29
- return undefined;
30
- return getOrComputeCachedValue(token, TokenContentSymbol, () => {
31
- const plaintext = getHiddenContent(token);
32
- if (!plaintext)
33
- throw new Error("Token is locked");
34
- const details = JSON.parse(plaintext);
35
- if (!details.mint)
36
- throw new Error("Token missing mint");
37
- if (!details.proofs)
38
- throw new Error("Token missing proofs");
39
- if (!details.del)
40
- details.del = [];
41
- return details;
42
- });
43
- }
44
- /** Returns if token details are locked */
45
- export function isTokenContentLocked(token) {
46
- return isHiddenContentLocked(token);
47
- }
48
- /** Decrypts a k:7375 token event */
49
- export async function unlockTokenContent(token, signer) {
50
- if (isHiddenContentLocked(token))
51
- await unlockHiddenContent(token, signer);
52
- return getTokenContent(token);
53
- }
54
- /** Removes the unencrypted hidden content */
55
- export function lockTokenContent(token) {
56
- Reflect.deleteProperty(token, TokenContentSymbol);
57
- lockHiddenContent(token);
58
- }
59
- /**
60
- * Gets the totaled amount of proofs in a token event
61
- * @param token The token event to calculate the total
62
- */
63
- export function getTokenProofsTotal(token) {
64
- if (isTokenContentLocked(token))
65
- return undefined;
66
- const content = getTokenContent(token);
67
- return content.proofs.reduce((t, p) => t + p.amount, 0);
68
- }
69
- /**
70
- * Selects oldest tokens and proofs that total up to more than the min amount
71
- * @throws
72
- */
73
- export function dumbTokenSelection(tokens, minAmount, mint) {
74
- // sort newest to oldest
75
- const sorted = tokens
76
- .filter((token) => !isTokenContentLocked(token) && (mint ? getTokenContent(token).mint === mint : true))
77
- .sort((a, b) => b.created_at - a.created_at);
78
- let amount = 0;
79
- const seen = new Set();
80
- const selectedTokens = [];
81
- const selectedProofs = [];
82
- while (amount < minAmount) {
83
- const token = sorted.pop();
84
- if (!token)
85
- throw new Error("Insufficient funds");
86
- const proofs = getTokenContent(token).proofs.filter(ignoreDuplicateProofs(seen));
87
- const total = proofs.reduce((t, p) => t + p.amount, 0);
88
- selectedTokens.push(token);
89
- selectedProofs.push(...proofs);
90
- amount += total;
91
- }
92
- return { events: selectedTokens, proofs: selectedProofs };
93
- }
94
- /**
95
- * Returns a decoded cashu token inside an unicode emoji
96
- * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/ReceiveTokenDialog.vue#L387
97
- */
98
- export function decodeTokenFromEmojiString(str) {
99
- try {
100
- let decoded = [];
101
- const chars = Array.from(str);
102
- if (!chars.length)
103
- return undefined;
104
- const fromVariationSelector = function (char) {
105
- const codePoint = char.codePointAt(0);
106
- if (codePoint === undefined)
107
- return null;
108
- // Handle Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
109
- if (codePoint >= 0xfe00 && codePoint <= 0xfe0f) {
110
- // Maps FE00->0, FE01->1, ..., FE0F->15
111
- const byteValue = codePoint - 0xfe00;
112
- return String.fromCharCode(byteValue);
113
- }
114
- // Handle Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
115
- if (codePoint >= 0xe0100 && codePoint <= 0xe01ef) {
116
- // Maps E0100->16, E0101->17, ..., E01EF->255
117
- const byteValue = codePoint - 0xe0100 + 16;
118
- return String.fromCharCode(byteValue);
119
- }
120
- // No Variation Selector
121
- return null;
122
- };
123
- // Check all input chars for peanut data
124
- for (const char of chars) {
125
- let byte = fromVariationSelector(char);
126
- if (byte === null && decoded.length > 0) {
127
- break;
128
- }
129
- else if (byte === null) {
130
- continue;
131
- }
132
- decoded.push(byte); // got some
133
- }
134
- // Switch out token if we found peanut data
135
- let decodedString = decoded.join("");
136
- return getDecodedToken(decodedString);
137
- }
138
- catch (error) {
139
- return undefined;
140
- }
141
- }
142
- /**
143
- * Encodes a token into an emoji char
144
- * @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/SendTokenDialog.vue#L710
145
- */
146
- export function encodeTokenToEmoji(token, emoji = "🥜") {
147
- return (emoji +
148
- Array.from(typeof token === "string" ? token : getEncodedToken(token))
149
- .map((char) => {
150
- const byteValue = char.charCodeAt(0);
151
- // For byte values 0-15, use Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
152
- if (byteValue >= 0 && byteValue <= 15) {
153
- return String.fromCodePoint(0xfe00 + byteValue);
154
- }
155
- // For byte values 16-255, use Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
156
- if (byteValue >= 16 && byteValue <= 255) {
157
- return String.fromCodePoint(0xe0100 + (byteValue - 16));
158
- }
159
- return "";
160
- })
161
- .join(""));
162
- }
@@ -1,15 +0,0 @@
1
- import { HiddenContentSigner } from "applesauce-core/helpers";
2
- import { NostrEvent } from "nostr-tools";
3
- export declare const WALLET_KIND = 17375;
4
- export declare const WALLET_BACKUP_KIND = 375;
5
- export declare const WalletPrivateKeySymbol: unique symbol;
6
- export declare const WalletMintsSymbol: unique symbol;
7
- /** Returns if a wallet is locked */
8
- export declare function isWalletLocked(wallet: NostrEvent): boolean;
9
- /** Unlocks a wallet and returns the hidden tags */
10
- export declare function unlockWallet(wallet: NostrEvent, signer: HiddenContentSigner): Promise<string[][]>;
11
- export declare function lockWallet(wallet: NostrEvent): void;
12
- /** Returns the wallets mints */
13
- export declare function getWalletMints(wallet: NostrEvent): string[];
14
- /** Returns the wallets private key as a string */
15
- export declare function getWalletPrivateKey(wallet: NostrEvent): Uint8Array | undefined;
@@ -1,41 +0,0 @@
1
- import { hexToBytes } from "@noble/hashes/utils";
2
- import { getHiddenTags, getOrComputeCachedValue, isHiddenTagsLocked, lockHiddenTags, setHiddenTagsEncryptionMethod, unlockHiddenTags, } from "applesauce-core/helpers";
3
- export const WALLET_KIND = 17375;
4
- export const WALLET_BACKUP_KIND = 375;
5
- // Enable hidden content for wallet kinds
6
- setHiddenTagsEncryptionMethod(WALLET_KIND, "nip44");
7
- setHiddenTagsEncryptionMethod(WALLET_BACKUP_KIND, "nip44");
8
- export const WalletPrivateKeySymbol = Symbol.for("wallet-private-key");
9
- export const WalletMintsSymbol = Symbol.for("wallet-mints");
10
- /** Returns if a wallet is locked */
11
- export function isWalletLocked(wallet) {
12
- return isHiddenTagsLocked(wallet);
13
- }
14
- /** Unlocks a wallet and returns the hidden tags */
15
- export async function unlockWallet(wallet, signer) {
16
- return await unlockHiddenTags(wallet, signer);
17
- }
18
- export function lockWallet(wallet) {
19
- Reflect.deleteProperty(wallet, WalletPrivateKeySymbol);
20
- Reflect.deleteProperty(wallet, WalletMintsSymbol);
21
- lockHiddenTags(wallet);
22
- }
23
- /** Returns the wallets mints */
24
- export function getWalletMints(wallet) {
25
- return getOrComputeCachedValue(wallet, WalletMintsSymbol, () => {
26
- const tags = getHiddenTags(wallet);
27
- if (!tags)
28
- throw new Error("Wallet is locked");
29
- return tags.filter((t) => t[0] === "mint").map((t) => t[1]);
30
- });
31
- }
32
- /** Returns the wallets private key as a string */
33
- export function getWalletPrivateKey(wallet) {
34
- return getOrComputeCachedValue(wallet, WalletPrivateKeySymbol, () => {
35
- const tags = getHiddenTags(wallet);
36
- if (!tags)
37
- throw new Error("Wallet is locked");
38
- const key = tags.find((t) => t[0] === "privkey" && t[1])?.[1];
39
- return key ? hexToBytes(key) : undefined;
40
- });
41
- }