applesauce-wallet-connect 0.0.0-next-20250808173123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/tokens.d.ts +17 -0
- package/dist/actions/tokens.js +110 -0
- package/dist/actions/wallet.d.ts +13 -0
- package/dist/actions/wallet.js +64 -0
- package/dist/actions/zap-info.d.ts +22 -0
- package/dist/actions/zap-info.js +83 -0
- package/dist/actions/zaps.d.ts +8 -0
- package/dist/actions/zaps.js +30 -0
- package/dist/blueprints/history.d.ts +4 -0
- package/dist/blueprints/history.js +11 -0
- package/dist/blueprints/index.d.ts +4 -0
- package/dist/blueprints/index.js +4 -0
- package/dist/blueprints/info.d.ts +4 -0
- package/dist/blueprints/info.js +8 -0
- package/dist/blueprints/notification.d.ts +15 -0
- package/dist/blueprints/notification.js +21 -0
- package/dist/blueprints/request.d.ts +9 -0
- package/dist/blueprints/request.js +12 -0
- package/dist/blueprints/response.d.ts +5 -0
- package/dist/blueprints/response.js +10 -0
- package/dist/blueprints/support.d.ts +4 -0
- package/dist/blueprints/support.js +8 -0
- package/dist/blueprints/tokens.d.ts +7 -0
- package/dist/blueprints/tokens.js +11 -0
- package/dist/blueprints/wallet.d.ts +5 -0
- package/dist/blueprints/wallet.js +11 -0
- package/dist/blueprints/zaps.d.ts +8 -0
- package/dist/blueprints/zaps.js +12 -0
- package/dist/helpers/animated-qr.d.ts +30 -0
- package/dist/helpers/animated-qr.js +71 -0
- package/dist/helpers/connect-uri.d.ts +12 -0
- package/dist/helpers/connect-uri.js +23 -0
- package/dist/helpers/encryption.d.ts +2 -0
- package/dist/helpers/encryption.js +1 -0
- package/dist/helpers/error.d.ts +55 -0
- package/dist/helpers/error.js +81 -0
- package/dist/helpers/history.d.ts +26 -0
- package/dist/helpers/history.js +47 -0
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.js +7 -0
- package/dist/helpers/info.d.ts +34 -0
- package/dist/helpers/info.js +97 -0
- package/dist/helpers/methods.d.ts +1 -0
- package/dist/helpers/methods.js +1 -0
- package/dist/helpers/notification.d.ts +28 -0
- package/dist/helpers/notification.js +28 -0
- package/dist/helpers/nutzap.d.ts +27 -0
- package/dist/helpers/nutzap.js +66 -0
- package/dist/helpers/request.d.ts +131 -0
- package/dist/helpers/request.js +51 -0
- package/dist/helpers/response.d.ts +138 -0
- package/dist/helpers/response.js +35 -0
- package/dist/helpers/support.d.ts +34 -0
- package/dist/helpers/support.js +97 -0
- package/dist/helpers/tokens.d.ts +58 -0
- package/dist/helpers/tokens.js +162 -0
- package/dist/helpers/wallet.d.ts +15 -0
- package/dist/helpers/wallet.js +41 -0
- package/dist/helpers/zap-info.d.ts +19 -0
- package/dist/helpers/zap-info.js +42 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/interface.d.ts +6 -0
- package/dist/interface.js +1 -0
- package/dist/models/history.d.ts +6 -0
- package/dist/models/history.js +21 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.js +4 -0
- package/dist/models/nutzap.d.ts +6 -0
- package/dist/models/nutzap.js +16 -0
- package/dist/models/tokens.d.ts +6 -0
- package/dist/models/tokens.js +58 -0
- package/dist/models/wallet.d.ts +13 -0
- package/dist/models/wallet.js +18 -0
- package/dist/operations/history.d.ts +7 -0
- package/dist/operations/history.js +34 -0
- package/dist/operations/index.d.ts +5 -0
- package/dist/operations/index.js +5 -0
- package/dist/operations/nutzap.d.ts +14 -0
- package/dist/operations/nutzap.js +33 -0
- package/dist/operations/tokens.d.ts +4 -0
- package/dist/operations/tokens.js +24 -0
- package/dist/operations/wallet.d.ts +8 -0
- package/dist/operations/wallet.js +30 -0
- package/dist/operations/zap-info.d.ts +10 -0
- package/dist/operations/zap-info.js +17 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +1 -0
- package/dist/wallet-connect.d.ts +111 -0
- package/dist/wallet-connect.js +271 -0
- package/dist/wallet-service.d.ts +111 -0
- package/dist/wallet-service.js +270 -0
- package/package.json +83 -0
|
@@ -0,0 +1,27 @@
|
|
|
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;
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { HiddenContentSigner } from "applesauce-core/helpers";
|
|
2
|
+
import { NostrEvent } from "nostr-tools";
|
|
3
|
+
import { WalletConnectEncryptionMethod } from "./encryption.js";
|
|
4
|
+
import { WalletMethod } from "./support.js";
|
|
5
|
+
export declare const WALLET_REQUEST_KIND = 23194;
|
|
6
|
+
/** A symbol used to cache the wallet request on the event */
|
|
7
|
+
export declare const WalletRequestSymbol: unique symbol;
|
|
8
|
+
/** TLV record for keysend payments */
|
|
9
|
+
export interface TLVRecord {
|
|
10
|
+
/** TLV type */
|
|
11
|
+
type: number;
|
|
12
|
+
/** Hex encoded TLV value */
|
|
13
|
+
value: string;
|
|
14
|
+
}
|
|
15
|
+
/** Base request structure for all NIP-47 requests */
|
|
16
|
+
export interface BaseWalletRequest<TMethod extends WalletMethod, TParams> {
|
|
17
|
+
/** The method to call */
|
|
18
|
+
method: TMethod;
|
|
19
|
+
/** Parameters for the method */
|
|
20
|
+
params: TParams;
|
|
21
|
+
}
|
|
22
|
+
/** Parameters for pay_invoice method */
|
|
23
|
+
export interface PayInvoiceParams {
|
|
24
|
+
/** BOLT11 invoice */
|
|
25
|
+
invoice: string;
|
|
26
|
+
/** Invoice amount in msats, optional */
|
|
27
|
+
amount?: number;
|
|
28
|
+
}
|
|
29
|
+
export type PayInvoiceRequest = BaseWalletRequest<"pay_invoice", PayInvoiceParams>;
|
|
30
|
+
/** Parameters for multi_pay_invoice method */
|
|
31
|
+
export interface MultiPayInvoiceParams {
|
|
32
|
+
/** Array of invoices to pay */
|
|
33
|
+
invoices: Array<{
|
|
34
|
+
/** ID to identify this invoice in the response */
|
|
35
|
+
id?: string;
|
|
36
|
+
/** BOLT11 invoice */
|
|
37
|
+
invoice: string;
|
|
38
|
+
/** Invoice amount in msats, optional */
|
|
39
|
+
amount?: number;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export type MultiPayInvoiceRequest = BaseWalletRequest<"multi_pay_invoice", MultiPayInvoiceParams>;
|
|
43
|
+
/** Parameters for pay_keysend method */
|
|
44
|
+
export interface PayKeysendParams {
|
|
45
|
+
/** Amount in msats, required */
|
|
46
|
+
amount: number;
|
|
47
|
+
/** Payee pubkey, required */
|
|
48
|
+
pubkey: string;
|
|
49
|
+
/** Preimage of the payment, optional */
|
|
50
|
+
preimage?: string;
|
|
51
|
+
/** TLV records, optional */
|
|
52
|
+
tlv_records?: TLVRecord[];
|
|
53
|
+
}
|
|
54
|
+
export type PayKeysendRequest = BaseWalletRequest<"pay_keysend", PayKeysendParams>;
|
|
55
|
+
/** Parameters for multi_pay_keysend method */
|
|
56
|
+
export interface MultiPayKeysendParams {
|
|
57
|
+
/** Array of keysend payments */
|
|
58
|
+
keysends: Array<{
|
|
59
|
+
/** ID to identify this keysend in the response */
|
|
60
|
+
id?: string;
|
|
61
|
+
/** Payee pubkey, required */
|
|
62
|
+
pubkey: string;
|
|
63
|
+
/** Amount in msats, required */
|
|
64
|
+
amount: number;
|
|
65
|
+
/** Preimage of the payment, optional */
|
|
66
|
+
preimage?: string;
|
|
67
|
+
/** TLV records, optional */
|
|
68
|
+
tlv_records?: TLVRecord[];
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
export type MultiPayKeysendRequest = BaseWalletRequest<"multi_pay_keysend", MultiPayKeysendParams>;
|
|
72
|
+
/** Parameters for make_invoice method */
|
|
73
|
+
export interface MakeInvoiceParams {
|
|
74
|
+
/** Value in msats */
|
|
75
|
+
amount: number;
|
|
76
|
+
/** Invoice's description, optional */
|
|
77
|
+
description?: string;
|
|
78
|
+
/** Invoice's description hash, optional */
|
|
79
|
+
description_hash?: string;
|
|
80
|
+
/** Expiry in seconds from time invoice is created, optional */
|
|
81
|
+
expiry?: number;
|
|
82
|
+
}
|
|
83
|
+
export type MakeInvoiceRequest = BaseWalletRequest<"make_invoice", MakeInvoiceParams>;
|
|
84
|
+
/** Parameters for lookup_invoice method */
|
|
85
|
+
export interface LookupInvoiceParams {
|
|
86
|
+
/** Payment hash of the invoice, one of payment_hash or invoice is required */
|
|
87
|
+
payment_hash?: string;
|
|
88
|
+
/** Invoice to lookup */
|
|
89
|
+
invoice?: string;
|
|
90
|
+
}
|
|
91
|
+
export type LookupInvoiceRequest = BaseWalletRequest<"lookup_invoice", LookupInvoiceParams>;
|
|
92
|
+
/** Parameters for list_transactions method */
|
|
93
|
+
export interface ListTransactionsParams {
|
|
94
|
+
/** Starting timestamp in seconds since epoch (inclusive), optional */
|
|
95
|
+
from?: number;
|
|
96
|
+
/** Ending timestamp in seconds since epoch (inclusive), optional */
|
|
97
|
+
until?: number;
|
|
98
|
+
/** Maximum number of invoices to return, optional */
|
|
99
|
+
limit?: number;
|
|
100
|
+
/** Offset of the first invoice to return, optional */
|
|
101
|
+
offset?: number;
|
|
102
|
+
/** Include unpaid invoices, optional, default false */
|
|
103
|
+
unpaid?: boolean;
|
|
104
|
+
/** "incoming" for invoices, "outgoing" for payments, undefined for both */
|
|
105
|
+
type?: "incoming" | "outgoing";
|
|
106
|
+
}
|
|
107
|
+
export type ListTransactionsRequest = BaseWalletRequest<"list_transactions", ListTransactionsParams>;
|
|
108
|
+
/** Parameters for get_balance method */
|
|
109
|
+
export interface GetBalanceParams {
|
|
110
|
+
}
|
|
111
|
+
export type GetBalanceRequest = BaseWalletRequest<"get_balance", GetBalanceParams>;
|
|
112
|
+
/** Parameters for get_info method */
|
|
113
|
+
export interface GetInfoParams {
|
|
114
|
+
}
|
|
115
|
+
export type GetInfoRequest = BaseWalletRequest<"get_info", GetInfoParams>;
|
|
116
|
+
/** Union type for all NIP-47 request types */
|
|
117
|
+
export type WalletRequest = PayInvoiceRequest | MultiPayInvoiceRequest | PayKeysendRequest | MultiPayKeysendRequest | MakeInvoiceRequest | LookupInvoiceRequest | ListTransactionsRequest | GetBalanceRequest | GetInfoRequest;
|
|
118
|
+
/** Checks if a kind 23194 event is locked */
|
|
119
|
+
export declare function isWalletRequestLocked(request: NostrEvent): boolean;
|
|
120
|
+
/** Unlocks a kind 23194 event */
|
|
121
|
+
export declare function unlockWalletRequest(request: NostrEvent, signer: HiddenContentSigner): Promise<WalletRequest | undefined | null>;
|
|
122
|
+
/** Gets the wallet request from a kind 23194 event */
|
|
123
|
+
export declare function getWalletRequest(request: NostrEvent): WalletRequest | undefined | null;
|
|
124
|
+
/** Returns the wallet service pubkey from a request */
|
|
125
|
+
export declare function getWalletRequestServicePubkey(request: NostrEvent): string | undefined;
|
|
126
|
+
/** Returns the expiration timestamp from a request */
|
|
127
|
+
export declare function getWalletRequestExpiration(request: NostrEvent): number | undefined;
|
|
128
|
+
/** Checks if a request has expired */
|
|
129
|
+
export declare function isWalletRequestExpired(request: NostrEvent): boolean;
|
|
130
|
+
/** Gets the encryption method used for a request */
|
|
131
|
+
export declare function getWalletRequestEncryption(request: NostrEvent): WalletConnectEncryptionMethod;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getHiddenContent, getOrComputeCachedValue, getTagValue, isHiddenContentLocked, isNIP04Encrypted, setHiddenContentEncryptionMethod, unixNow, unlockHiddenContent, } from "applesauce-core/helpers";
|
|
2
|
+
export const WALLET_REQUEST_KIND = 23194;
|
|
3
|
+
// Set the encryption method to use for request kind
|
|
4
|
+
setHiddenContentEncryptionMethod(WALLET_REQUEST_KIND, "nip44");
|
|
5
|
+
/** A symbol used to cache the wallet request on the event */
|
|
6
|
+
export const WalletRequestSymbol = Symbol("wallet-request");
|
|
7
|
+
/** Checks if a kind 23194 event is locked */
|
|
8
|
+
export function isWalletRequestLocked(request) {
|
|
9
|
+
return isHiddenContentLocked(request);
|
|
10
|
+
}
|
|
11
|
+
/** Unlocks a kind 23194 event */
|
|
12
|
+
export async function unlockWalletRequest(request, signer) {
|
|
13
|
+
await unlockHiddenContent(request, signer);
|
|
14
|
+
return getWalletRequest(request);
|
|
15
|
+
}
|
|
16
|
+
/** Gets the wallet request from a kind 23194 event */
|
|
17
|
+
export function getWalletRequest(request) {
|
|
18
|
+
if (isWalletRequestLocked(request))
|
|
19
|
+
return undefined;
|
|
20
|
+
return getOrComputeCachedValue(request, WalletRequestSymbol, () => {
|
|
21
|
+
const content = getHiddenContent(request);
|
|
22
|
+
if (!content)
|
|
23
|
+
return null;
|
|
24
|
+
return JSON.parse(content);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Returns the wallet service pubkey from a request */
|
|
28
|
+
export function getWalletRequestServicePubkey(request) {
|
|
29
|
+
return getTagValue(request, "p");
|
|
30
|
+
}
|
|
31
|
+
/** Returns the expiration timestamp from a request */
|
|
32
|
+
export function getWalletRequestExpiration(request) {
|
|
33
|
+
const expiration = getTagValue(request, "expiration");
|
|
34
|
+
return expiration ? parseInt(expiration, 10) : undefined;
|
|
35
|
+
}
|
|
36
|
+
/** Checks if a request has expired */
|
|
37
|
+
export function isWalletRequestExpired(request) {
|
|
38
|
+
const expiration = getWalletRequestExpiration(request);
|
|
39
|
+
if (!expiration)
|
|
40
|
+
return false;
|
|
41
|
+
return unixNow() > expiration;
|
|
42
|
+
}
|
|
43
|
+
/** Gets the encryption method used for a request */
|
|
44
|
+
export function getWalletRequestEncryption(request) {
|
|
45
|
+
const encryption = getTagValue(request, "encryption");
|
|
46
|
+
return encryption
|
|
47
|
+
? encryption
|
|
48
|
+
: isNIP04Encrypted(request.content)
|
|
49
|
+
? "nip04"
|
|
50
|
+
: "nip44_v2";
|
|
51
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { EncryptionMethod, HiddenContentSigner } from "applesauce-core/helpers";
|
|
2
|
+
import { NostrEvent } from "nostr-tools";
|
|
3
|
+
import { WalletErrorCode } from "./error.js";
|
|
4
|
+
import { WalletMethod } from "./support.js";
|
|
5
|
+
import { NotificationType } from "./notification.js";
|
|
6
|
+
export declare const WALLET_RESPONSE_KIND = 23195;
|
|
7
|
+
/** A symbol used to cache the wallet response on the event */
|
|
8
|
+
export declare const WalletResponseSymbol: unique symbol;
|
|
9
|
+
/** Error object for wallet responses */
|
|
10
|
+
export interface WalletResponseError {
|
|
11
|
+
type: WalletErrorCode;
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
/** Base response structure for all NIP-47 responses */
|
|
15
|
+
export type BaseWalletResponse<TResultType extends WalletMethod, TResult> = {
|
|
16
|
+
/** Indicates the structure of the result field */
|
|
17
|
+
result_type: TResultType;
|
|
18
|
+
/** Error object, non-null in case of error */
|
|
19
|
+
error: WalletResponseError;
|
|
20
|
+
result: null;
|
|
21
|
+
} | {
|
|
22
|
+
/** Indicates the structure of the result field */
|
|
23
|
+
result_type: TResultType;
|
|
24
|
+
error: null;
|
|
25
|
+
/** Result object, null in case of error */
|
|
26
|
+
result: TResult;
|
|
27
|
+
};
|
|
28
|
+
/** Transaction object used in multiple response types */
|
|
29
|
+
export interface Transaction {
|
|
30
|
+
/** Type of transaction */
|
|
31
|
+
type: "incoming" | "outgoing";
|
|
32
|
+
/** State of the transaction */
|
|
33
|
+
state: "pending" | "settled" | "expired" | "failed";
|
|
34
|
+
/** Value in msats */
|
|
35
|
+
amount: number;
|
|
36
|
+
/** Value in msats */
|
|
37
|
+
fees_paid: number;
|
|
38
|
+
/** Invoice/payment creation unix timestamp */
|
|
39
|
+
created_at: number;
|
|
40
|
+
/** Encoded invoice, optional */
|
|
41
|
+
invoice?: string;
|
|
42
|
+
/** Invoice's description, optional */
|
|
43
|
+
description?: string;
|
|
44
|
+
/** Invoice's description hash, optional */
|
|
45
|
+
description_hash?: string;
|
|
46
|
+
/** Payment's preimage, optional if unpaid */
|
|
47
|
+
preimage?: string;
|
|
48
|
+
/** Payment hash for the payment, optional */
|
|
49
|
+
payment_hash?: string;
|
|
50
|
+
/** Invoice expiration unix timestamp, optional if not applicable */
|
|
51
|
+
expires_at?: number;
|
|
52
|
+
/** Invoice/payment settlement unix timestamp, optional if unpaid */
|
|
53
|
+
settled_at?: number;
|
|
54
|
+
/** Generic metadata that can be used to add things like zap/boostagram details */
|
|
55
|
+
metadata?: Record<string, any>;
|
|
56
|
+
}
|
|
57
|
+
/** Response for pay_invoice method */
|
|
58
|
+
export interface PayInvoiceResult {
|
|
59
|
+
/** Preimage of the payment */
|
|
60
|
+
preimage: string;
|
|
61
|
+
/** Value in msats, optional */
|
|
62
|
+
fees_paid?: number;
|
|
63
|
+
}
|
|
64
|
+
export type PayInvoiceResponse = BaseWalletResponse<"pay_invoice", PayInvoiceResult>;
|
|
65
|
+
/** Response for multi_pay_invoice method */
|
|
66
|
+
export interface MultiPayInvoiceResult {
|
|
67
|
+
/** Preimage of the payment */
|
|
68
|
+
preimage: string;
|
|
69
|
+
/** Value in msats, optional */
|
|
70
|
+
fees_paid?: number;
|
|
71
|
+
}
|
|
72
|
+
export type MultiPayInvoiceResponse = BaseWalletResponse<"multi_pay_invoice", MultiPayInvoiceResult>;
|
|
73
|
+
/** Response for pay_keysend method */
|
|
74
|
+
export interface PayKeysendResult {
|
|
75
|
+
/** Preimage of the payment */
|
|
76
|
+
preimage: string;
|
|
77
|
+
/** Value in msats, optional */
|
|
78
|
+
fees_paid?: number;
|
|
79
|
+
}
|
|
80
|
+
export type PayKeysendResponse = BaseWalletResponse<"pay_keysend", PayKeysendResult>;
|
|
81
|
+
/** Response for multi_pay_keysend method */
|
|
82
|
+
export interface MultiPayKeysendResult {
|
|
83
|
+
/** Preimage of the payment */
|
|
84
|
+
preimage: string;
|
|
85
|
+
/** Value in msats, optional */
|
|
86
|
+
fees_paid?: number;
|
|
87
|
+
}
|
|
88
|
+
export type MultiPayKeysendResponse = BaseWalletResponse<"multi_pay_keysend", MultiPayKeysendResult>;
|
|
89
|
+
/** Response for make_invoice method */
|
|
90
|
+
export type MakeInvoiceResult = Transaction;
|
|
91
|
+
export type MakeInvoiceResponse = BaseWalletResponse<"make_invoice", MakeInvoiceResult>;
|
|
92
|
+
/** Response for lookup_invoice method */
|
|
93
|
+
export type LookupInvoiceResult = Transaction;
|
|
94
|
+
export type LookupInvoiceResponse = BaseWalletResponse<"lookup_invoice", LookupInvoiceResult>;
|
|
95
|
+
/** Response for list_transactions method */
|
|
96
|
+
export interface ListTransactionsResult {
|
|
97
|
+
/** Array of transactions */
|
|
98
|
+
transactions: Transaction[];
|
|
99
|
+
}
|
|
100
|
+
export type ListTransactionsResponse = BaseWalletResponse<"list_transactions", ListTransactionsResult>;
|
|
101
|
+
/** Response for get_balance method */
|
|
102
|
+
export interface GetBalanceResult {
|
|
103
|
+
/** User's balance in msats */
|
|
104
|
+
balance: number;
|
|
105
|
+
}
|
|
106
|
+
export type GetBalanceResponse = BaseWalletResponse<"get_balance", GetBalanceResult>;
|
|
107
|
+
/** Response for get_info method */
|
|
108
|
+
export interface GetInfoResult {
|
|
109
|
+
/** Node alias */
|
|
110
|
+
alias: string;
|
|
111
|
+
/** Node color as hex string */
|
|
112
|
+
color: string;
|
|
113
|
+
/** Node public key as hex string */
|
|
114
|
+
pubkey: string;
|
|
115
|
+
/** Network type */
|
|
116
|
+
network: "mainnet" | "testnet" | "signet" | "regtest";
|
|
117
|
+
/** Current block height */
|
|
118
|
+
block_height: number;
|
|
119
|
+
/** Current block hash as hex string */
|
|
120
|
+
block_hash: string;
|
|
121
|
+
/** List of supported methods for this connection */
|
|
122
|
+
methods: WalletMethod[];
|
|
123
|
+
/** List of supported notifications for this connection, optional */
|
|
124
|
+
notifications?: NotificationType[];
|
|
125
|
+
}
|
|
126
|
+
export type GetInfoResponse = BaseWalletResponse<"get_info", GetInfoResult>;
|
|
127
|
+
/** Union type for all NIP-47 response types */
|
|
128
|
+
export type WalletResponse = PayInvoiceResponse | MultiPayInvoiceResponse | PayKeysendResponse | MultiPayKeysendResponse | MakeInvoiceResponse | LookupInvoiceResponse | ListTransactionsResponse | GetBalanceResponse | GetInfoResponse;
|
|
129
|
+
/** Checks if a kind 23195 event is locked */
|
|
130
|
+
export declare function isWalletResponseLocked(response: NostrEvent): boolean;
|
|
131
|
+
/** Unlocks a kind 23195 event */
|
|
132
|
+
export declare function unlockWalletResponse(response: NostrEvent, signer: HiddenContentSigner, override?: EncryptionMethod): Promise<WalletResponse | undefined | null>;
|
|
133
|
+
/** Gets the wallet response from a kind 23195 event */
|
|
134
|
+
export declare function getWalletResponse(response: NostrEvent): WalletResponse | undefined | null;
|
|
135
|
+
/** Returns the client pubkey of client this response is for */
|
|
136
|
+
export declare function getWalletResponseClientPubkey(response: NostrEvent): string | undefined;
|
|
137
|
+
/** Returns the request id of the request this response is for */
|
|
138
|
+
export declare function getWalletResponseRequestId(response: NostrEvent): string | undefined;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getHiddenContent, getOrComputeCachedValue, getTagValue, isHiddenContentLocked, isNIP04Encrypted, setHiddenContentEncryptionMethod, unlockHiddenContent, } from "applesauce-core/helpers";
|
|
2
|
+
export const WALLET_RESPONSE_KIND = 23195;
|
|
3
|
+
// Set the encryption method to use for response kind
|
|
4
|
+
setHiddenContentEncryptionMethod(WALLET_RESPONSE_KIND, "nip04");
|
|
5
|
+
/** A symbol used to cache the wallet response on the event */
|
|
6
|
+
export const WalletResponseSymbol = Symbol("wallet-response");
|
|
7
|
+
/** Checks if a kind 23195 event is locked */
|
|
8
|
+
export function isWalletResponseLocked(response) {
|
|
9
|
+
return isHiddenContentLocked(response);
|
|
10
|
+
}
|
|
11
|
+
/** Unlocks a kind 23195 event */
|
|
12
|
+
export async function unlockWalletResponse(response, signer, override) {
|
|
13
|
+
const encryption = override ?? (!isNIP04Encrypted(response.content) ? "nip44" : "nip04");
|
|
14
|
+
await unlockHiddenContent(response, signer, encryption);
|
|
15
|
+
return getWalletResponse(response);
|
|
16
|
+
}
|
|
17
|
+
/** Gets the wallet response from a kind 23195 event */
|
|
18
|
+
export function getWalletResponse(response) {
|
|
19
|
+
if (isWalletResponseLocked(response))
|
|
20
|
+
return undefined;
|
|
21
|
+
return getOrComputeCachedValue(response, WalletResponseSymbol, () => {
|
|
22
|
+
const content = getHiddenContent(response);
|
|
23
|
+
if (!content)
|
|
24
|
+
return null;
|
|
25
|
+
return JSON.parse(content);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Returns the client pubkey of client this response is for */
|
|
29
|
+
export function getWalletResponseClientPubkey(response) {
|
|
30
|
+
return getTagValue(response, "p");
|
|
31
|
+
}
|
|
32
|
+
/** Returns the request id of the request this response is for */
|
|
33
|
+
export function getWalletResponseRequestId(response) {
|
|
34
|
+
return getTagValue(response, "e");
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
|
+
import { WalletConnectEncryptionMethod } from "./encryption.js";
|
|
3
|
+
import { NotificationType as NotificationType } from "./notification.js";
|
|
4
|
+
export declare const WALLET_INFO_KIND = 13194;
|
|
5
|
+
/** A symbol used to cache the wallet info on the event */
|
|
6
|
+
export declare const WalletInfoSymbol: unique symbol;
|
|
7
|
+
export type WalletMethod = "pay_invoice" | "multi_pay_invoice" | "pay_keysend" | "multi_pay_keysend" | "make_invoice" | "lookup_invoice" | "list_transactions" | "get_balance" | "get_info";
|
|
8
|
+
/** Wallet service capabilities and information */
|
|
9
|
+
export interface WalletSupport {
|
|
10
|
+
/** List of supported methods for this wallet service */
|
|
11
|
+
methods: WalletMethod[];
|
|
12
|
+
/** List of supported encryption methods */
|
|
13
|
+
encryption: WalletConnectEncryptionMethod[];
|
|
14
|
+
/** List of supported notifications, optional */
|
|
15
|
+
notifications?: NotificationType[];
|
|
16
|
+
}
|
|
17
|
+
/** Gets the wallet info from a kind 13194 event */
|
|
18
|
+
export declare function getWalletSupport(info: NostrEvent): WalletSupport | null;
|
|
19
|
+
/** Gets the encryption methods from a wallet info event */
|
|
20
|
+
export declare function getEncryptionMethods(info: NostrEvent | WalletSupport): WalletConnectEncryptionMethod[];
|
|
21
|
+
/** Checks if the wallet service supports a specific encryption method */
|
|
22
|
+
export declare function supportsEncryption(info: NostrEvent | WalletSupport, encryption: WalletConnectEncryptionMethod): boolean;
|
|
23
|
+
/** Gets the preferred encryption method (nip44_v2 preferred over nip04) */
|
|
24
|
+
export declare function getPreferredEncryption(info: NostrEvent | WalletSupport): WalletConnectEncryptionMethod;
|
|
25
|
+
/** Checks if the wallet service supports a specific method */
|
|
26
|
+
export declare function supportsMethod(info: NostrEvent | WalletSupport, method: WalletMethod): boolean;
|
|
27
|
+
/** Checks if the wallet service supports notifications */
|
|
28
|
+
export declare function supportsNotifications(info: NostrEvent | WalletSupport): boolean;
|
|
29
|
+
/** Checks if the wallet service supports a specific notification type */
|
|
30
|
+
export declare function supportsNotificationType(info: NostrEvent | WalletSupport, notificationType: NotificationType): boolean;
|
|
31
|
+
/** Gets all supported methods from the wallet info */
|
|
32
|
+
export declare function getSupportedMethods(info: NostrEvent | WalletSupport): WalletMethod[];
|
|
33
|
+
/** Gets all supported notifications from the wallet info */
|
|
34
|
+
export declare function getSupportedNotifications(info: NostrEvent | WalletSupport): NotificationType[];
|
|
@@ -0,0 +1,97 @@
|
|
|
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 getWalletSupport(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) ? getWalletSupport(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) ? getWalletSupport(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) ? getWalletSupport(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) ? getWalletSupport(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) ? getWalletSupport(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) ? getWalletSupport(info) : info;
|
|
96
|
+
return walletInfo?.notifications ?? [];
|
|
97
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
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;
|