applesauce-wallet 0.0.0-next-20250313155042 → 0.0.0-next-20250314133024
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/__tests__/wallet.test.js +4 -5
- package/dist/actions/tokens.js +10 -10
- package/dist/actions/wallet.js +5 -4
- package/dist/helpers/__tests__/tokens.test.js +24 -1
- package/dist/helpers/history.d.ts +1 -0
- package/dist/helpers/history.js +5 -1
- package/dist/helpers/tokens.d.ts +13 -0
- package/dist/helpers/tokens.js +77 -1
- package/dist/helpers/wallet.d.ts +1 -0
- package/dist/helpers/wallet.js +6 -1
- package/dist/queries/__tests__/wallet.test.js +2 -1
- package/package.json +5 -5
|
@@ -6,6 +6,7 @@ import { FakeUser } from "../../__tests__/fake-user.js";
|
|
|
6
6
|
import { CreateWallet } from "../wallet.js";
|
|
7
7
|
import { WALLET_BACKUP_KIND } from "../../helpers/wallet.js";
|
|
8
8
|
import { unlockHiddenTags } from "applesauce-core/helpers";
|
|
9
|
+
import { lastValueFrom } from "rxjs";
|
|
9
10
|
const user = new FakeUser();
|
|
10
11
|
let events;
|
|
11
12
|
let factory;
|
|
@@ -20,13 +21,11 @@ beforeEach(() => {
|
|
|
20
21
|
describe("CreateWallet", () => {
|
|
21
22
|
it("should publish a wallet backup event", async () => {
|
|
22
23
|
await hub.run(CreateWallet, ["https://mint.money.com"]);
|
|
23
|
-
expect(publish).toHaveBeenCalledWith(expect.
|
|
24
|
+
expect(publish).toHaveBeenCalledWith(expect.objectContaining({ kind: WALLET_BACKUP_KIND }));
|
|
24
25
|
});
|
|
25
26
|
it("should publish a wallet event with mints", async () => {
|
|
26
|
-
await hub.
|
|
27
|
-
|
|
28
|
-
const walletEvent = publish.mock.calls[1][1];
|
|
29
|
-
const hiddenTags = await unlockHiddenTags(walletEvent, user);
|
|
27
|
+
const event = await lastValueFrom(hub.exec(CreateWallet, ["https://mint.money.com"]));
|
|
28
|
+
const hiddenTags = await unlockHiddenTags(event, user);
|
|
30
29
|
// the second call should be the wallet event
|
|
31
30
|
expect(hiddenTags).toEqual(expect.arrayContaining([["mint", "https://mint.money.com"]]));
|
|
32
31
|
});
|
package/dist/actions/tokens.js
CHANGED
|
@@ -8,17 +8,17 @@ import { WalletHistoryBlueprint } from "../blueprints/history.js";
|
|
|
8
8
|
* @param redeemed an array of nutzap event ids to mark as redeemed
|
|
9
9
|
*/
|
|
10
10
|
export function ReceiveToken(token, redeemed, fee) {
|
|
11
|
-
return async ({ factory
|
|
11
|
+
return async function* ({ factory }) {
|
|
12
12
|
const amount = token.proofs.reduce((t, p) => t + p.amount, 0);
|
|
13
13
|
const tokenEvent = await factory.sign(await factory.create(WalletTokenBlueprint, token, []));
|
|
14
14
|
const history = await factory.sign(await factory.create(WalletHistoryBlueprint, { direction: "in", amount, mint: token.mint, created: [tokenEvent.id], fee }, redeemed ?? []));
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
yield tokenEvent;
|
|
16
|
+
yield history;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
/** An action that deletes old tokens and creates a new one but does not add a history event */
|
|
20
20
|
export function RolloverTokens(tokens, token) {
|
|
21
|
-
return async ({ factory
|
|
21
|
+
return async function* ({ factory }) {
|
|
22
22
|
// create a delete event for old tokens
|
|
23
23
|
const deleteDraft = await factory.create(DeleteBlueprint, tokens);
|
|
24
24
|
// create a new token event
|
|
@@ -27,13 +27,13 @@ export function RolloverTokens(tokens, token) {
|
|
|
27
27
|
const signedDelete = await factory.sign(deleteDraft);
|
|
28
28
|
const signedToken = await factory.sign(tokenDraft);
|
|
29
29
|
// publish events
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
yield signedDelete;
|
|
31
|
+
yield signedToken;
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
/** An action that deletes old token events and adds a spend history item */
|
|
35
35
|
export function CompleteSpend(spent, change) {
|
|
36
|
-
return async ({ factory
|
|
36
|
+
return async function* ({ factory }) {
|
|
37
37
|
if (spent.length === 0)
|
|
38
38
|
throw new Error("Cant complete spent with no token events");
|
|
39
39
|
if (spent.some((s) => isTokenContentLocked(s)))
|
|
@@ -56,9 +56,9 @@ export function CompleteSpend(spent, change) {
|
|
|
56
56
|
// sign history
|
|
57
57
|
const signedHistory = await factory.sign(history);
|
|
58
58
|
// publish events
|
|
59
|
-
|
|
59
|
+
yield signedDelete;
|
|
60
60
|
if (signedToken)
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
yield signedToken;
|
|
62
|
+
yield signedHistory;
|
|
63
63
|
};
|
|
64
64
|
}
|
package/dist/actions/wallet.js
CHANGED
|
@@ -5,19 +5,20 @@ import { isTokenContentLocked, unlockTokenContent, WALLET_TOKEN_KIND } from "../
|
|
|
5
5
|
import { isHistoryContentLocked, unlockHistoryContent, WALLET_HISTORY_KIND } from "../helpers/history.js";
|
|
6
6
|
/** An action that creates a new 17375 wallet event and 375 wallet backup */
|
|
7
7
|
export function CreateWallet(mints, privateKey = generateSecretKey()) {
|
|
8
|
-
return async ({ events, factory, self
|
|
8
|
+
return async function* ({ events, factory, self }) {
|
|
9
9
|
const existing = events.getReplaceable(WALLET_KIND, self);
|
|
10
10
|
if (existing)
|
|
11
11
|
throw new Error("Wallet already exists");
|
|
12
12
|
const wallet = await factory.sign(await factory.create(WalletBlueprint, privateKey, mints));
|
|
13
13
|
const backup = await factory.sign(await factory.create(WalletBackupBlueprint, wallet));
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// publish the backup first
|
|
15
|
+
yield backup;
|
|
16
|
+
yield wallet;
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
/** Unlocks the wallet event and optionally the tokens and history events */
|
|
19
20
|
export function UnlockWallet(unlock) {
|
|
20
|
-
return async ({ events, self, factory })
|
|
21
|
+
return async function* ({ events, self, factory }) {
|
|
21
22
|
const signer = factory.context.signer;
|
|
22
23
|
if (!signer)
|
|
23
24
|
throw new Error("Missing signer");
|
|
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { EventFactory } from "applesauce-factory";
|
|
3
3
|
import { FakeUser } from "../../__tests__/fake-user.js";
|
|
4
4
|
import { WalletTokenBlueprint } from "../../blueprints/tokens.js";
|
|
5
|
-
import { dumbTokenSelection, unlockTokenContent } from "../tokens.js";
|
|
5
|
+
import { decodeTokenFromEmojiString, dumbTokenSelection, encodeTokenToEmoji, unlockTokenContent } from "../tokens.js";
|
|
6
6
|
import { HiddenContentSymbol } from "applesauce-core/helpers";
|
|
7
7
|
const user = new FakeUser();
|
|
8
8
|
const factory = new EventFactory({ signer: user });
|
|
@@ -62,3 +62,26 @@ describe("dumbTokenSelection", () => {
|
|
|
62
62
|
expect(dumbTokenSelection([a, b], 20)).toEqual([a]);
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
|
+
describe("encodeTokenToEmoji", () => {
|
|
66
|
+
it("should encode token into emoji string", () => {
|
|
67
|
+
const token = "cashuBo2FteBtodHRwczovL3Rlc3RudXQuY2FzaHUuc3BhY2VhdWNzYXRhdIGiYWlIAJofKTJT5B5hcIGkYWEBYXN4QDdlZDBkMzk3NGQ5ZWM2OTc2YTAzYmZmYjdkMTA4NzIzZTBiMDRjMzRhNDc3MjlmNjMwOGJlODc3OTA2NTY0NDVhY1ghA36iYyOHCe4CnTxzORbcXFVeAbkMUFE6FqPWInujnAOcYWSjYWVYIJmHRwCQ0Uopkd3P5xb0MdcWQEaZz9hXWtcn-FMhZj8LYXNYIF4X9ybXxg5Pp0KSowfu4y_Aovo9iy3TXlLSaKyVJzz2YXJYIC_UFkoC5U9BpSgBTGUQgsjfz_emv5xykDiavZUfRN8E";
|
|
68
|
+
expect(encodeTokenToEmoji(token).length).toBeGreaterThan(token.length);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
const emoji = "🥜󠅓󠅑󠅣󠅘󠅥󠄲󠅟󠄢󠄶󠅤󠅕󠄲󠅤󠅟󠅔󠄸󠅂󠅧󠅓󠅪󠅟󠅦󠄼󠄣󠅂󠅜󠅓󠄣󠅂󠅥󠅔󠅈󠅁󠅥󠅉󠄢󠄶󠅪󠅑󠄸󠅅󠅥󠅓󠄣󠄲󠅘󠅉󠄢󠅆󠅘󠅔󠅇󠄾󠅪󠅉󠅈󠅂󠅘󠅔󠄹󠄷󠅙󠅉󠅇󠅜󠄹󠄱󠄺󠅟󠅖󠄻󠅄󠄺󠅄󠄥󠄲󠄥󠅘󠅓󠄹󠄷󠅛󠅉󠅇󠄵󠄲󠅉󠅈󠄾󠄤󠅁󠄴󠅔󠅜󠅊󠄴󠄲󠅛󠄽󠅪󠅛󠄣󠄾󠄷󠅁󠄥󠅊󠅇󠄽󠄢󠄿󠅄󠅓󠄢󠅉󠅄󠄱󠅪󠅉󠅝󠅊󠅝󠅉󠅚󠅔󠅛󠄽󠅄󠄱󠄤󠄾󠅪󠄹󠅪󠅊󠅄󠄲󠅙󠄽󠄴󠅂󠅚󠄽󠅪󠅂󠅘󠄾󠄴󠅓󠄣󠄽󠅚󠅜󠅝󠄾󠅚󠄽󠅧󠄿󠄷󠄺󠅜󠄿󠄴󠅓󠄣󠄿󠅄󠄱󠄢󠄾󠅄󠅉󠄠󠄾󠄴󠅆󠅘󠅉󠄡󠅗󠅘󠄱󠄣󠄦󠅙󠅉󠅩󠄿󠄸󠄳󠅕󠄤󠄳󠅞󠅄󠅨󠅪󠄿󠅂󠅒󠅓󠅈󠄶󠅆󠅕󠄱󠅒󠅛󠄽󠅅󠄶󠄵󠄦󠄶󠅡󠅀󠅇󠄹󠅞󠅥󠅚󠅞󠄱󠄿󠅓󠅉󠅇󠅃󠅚󠅉󠅇󠅆󠅉󠄹󠄺󠅝󠄸󠅂󠅧󠄳󠅁󠄠󠅅󠅟󠅠󠅛󠅔󠄣󠅀󠄥󠅨󠅒󠄠󠄽󠅔󠅓󠅇󠅁󠄵󠅑󠅊󠅪󠄩󠅘󠅈󠅇󠅤󠅓󠅞󠄝󠄶󠄽󠅘󠅊󠅚󠄨󠄼󠅉󠅈󠄾󠅉󠄹󠄶󠄤󠅈󠄩󠅩󠅒󠅈󠅨󠅗󠄥󠅀󠅠󠄠󠄻󠅃󠅟󠅧󠅖󠅥󠄤󠅩󠅏󠄱󠅟󠅦󠅟󠄩󠅙󠅩󠄣󠅄󠅈󠅜󠄼󠅃󠅑󠄻󠅩󠅆󠄺󠅪󠅪󠄢󠅉󠅈󠄺󠅉󠄹󠄳󠅏󠅅󠄶󠅛󠅟󠄳󠄥󠅅󠄩󠄲󠅠󠅃󠅗󠄲󠅄󠄷󠅅󠅁󠅗󠅣󠅚󠅖󠅪󠅏󠅕󠅝󠅦󠄥󠅨󠅩󠅛󠄴󠅙󠅑󠅦󠅊󠅅󠅖󠅂󠄾󠄨󠄵";
|
|
72
|
+
describe("decodeTokenFromEmojiString", () => {
|
|
73
|
+
it("should decode single emoji", () => {
|
|
74
|
+
expect(decodeTokenFromEmojiString(emoji)).toEqual(expect.objectContaining({
|
|
75
|
+
mint: "https://testnut.cashu.space",
|
|
76
|
+
proofs: [expect.any(Object)],
|
|
77
|
+
unit: "sat",
|
|
78
|
+
}));
|
|
79
|
+
});
|
|
80
|
+
it("should decode an emoji in text", () => {
|
|
81
|
+
expect(decodeTokenFromEmojiString("the money is in the emoji, " + emoji + " you can redeem it using cashu.me")).toEqual(expect.objectContaining({
|
|
82
|
+
mint: "https://testnut.cashu.space",
|
|
83
|
+
proofs: [expect.any(Object)],
|
|
84
|
+
unit: "sat",
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -23,3 +23,4 @@ export declare function isHistoryContentLocked(history: NostrEvent): boolean;
|
|
|
23
23
|
export declare function getHistoryContent(history: NostrEvent): HistoryContent | undefined;
|
|
24
24
|
/** Decrypts a wallet history event */
|
|
25
25
|
export declare function unlockHistoryContent(history: NostrEvent, signer: HiddenContentSigner): Promise<HistoryContent>;
|
|
26
|
+
export declare function lockHistoryContent(history: NostrEvent): void;
|
package/dist/helpers/history.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHiddenTags, getOrComputeCachedValue, isETag, isHiddenContentLocked, isHiddenTagsLocked, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
1
|
+
import { getHiddenTags, getOrComputeCachedValue, isETag, isHiddenContentLocked, isHiddenTagsLocked, lockHiddenTags, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
2
2
|
export const WALLET_HISTORY_KIND = 7376;
|
|
3
3
|
export const HistoryContentSymbol = Symbol.for("history-content");
|
|
4
4
|
/** returns an array of redeemed event ids in a history event */
|
|
@@ -39,3 +39,7 @@ export async function unlockHistoryContent(history, signer) {
|
|
|
39
39
|
await unlockHiddenTags(history, signer);
|
|
40
40
|
return getHistoryContent(history);
|
|
41
41
|
}
|
|
42
|
+
export function lockHistoryContent(history) {
|
|
43
|
+
Reflect.deleteProperty(history, HistoryContentSymbol);
|
|
44
|
+
lockHiddenTags(history);
|
|
45
|
+
}
|
package/dist/helpers/tokens.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Token } from "@cashu/cashu-ts";
|
|
1
2
|
import { HiddenContentSigner } from "applesauce-core/helpers";
|
|
2
3
|
import { NostrEvent } from "nostr-tools";
|
|
3
4
|
export declare const WALLET_TOKEN_KIND = 7375;
|
|
@@ -27,6 +28,8 @@ export declare function getTokenContent(token: NostrEvent): TokenContent | undef
|
|
|
27
28
|
export declare function isTokenContentLocked(token: NostrEvent): boolean;
|
|
28
29
|
/** Decrypts a k:7375 token event */
|
|
29
30
|
export declare function unlockTokenContent(token: NostrEvent, signer: HiddenContentSigner): Promise<TokenContent>;
|
|
31
|
+
/** Removes the unencrypted hidden content */
|
|
32
|
+
export declare function lockTokenContent(token: NostrEvent): void;
|
|
30
33
|
/** Gets the totaled amount of proofs in a token event */
|
|
31
34
|
export declare function getTokenProofsTotal(token: NostrEvent): number | undefined;
|
|
32
35
|
/**
|
|
@@ -34,3 +37,13 @@ export declare function getTokenProofsTotal(token: NostrEvent): number | undefin
|
|
|
34
37
|
* @throws
|
|
35
38
|
*/
|
|
36
39
|
export declare function dumbTokenSelection(tokens: NostrEvent[], minAmount: number, mint?: string): import("nostr-tools").Event[];
|
|
40
|
+
/**
|
|
41
|
+
* Returns a decoded cashu token inside an unicode emoji
|
|
42
|
+
* @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/ReceiveTokenDialog.vue#L387
|
|
43
|
+
*/
|
|
44
|
+
export declare function decodeTokenFromEmojiString(str: string): Token | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Encodes a token into an emoji char
|
|
47
|
+
* @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/SendTokenDialog.vue#L710
|
|
48
|
+
*/
|
|
49
|
+
export declare function encodeTokenToEmoji(token: Token | string, emoji?: string): string;
|
package/dist/helpers/tokens.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getDecodedToken, getEncodedToken } from "@cashu/cashu-ts";
|
|
2
|
+
import { getHiddenContent, getOrComputeCachedValue, isHiddenContentLocked, isHiddenTagsLocked, lockHiddenContent, unlockHiddenContent, } from "applesauce-core/helpers";
|
|
2
3
|
export const WALLET_TOKEN_KIND = 7375;
|
|
3
4
|
export const TokenContentSymbol = Symbol.for("token-content");
|
|
4
5
|
export const TokenProofsTotalSymbol = Symbol.for("token-proofs-total");
|
|
@@ -33,6 +34,12 @@ export async function unlockTokenContent(token, signer) {
|
|
|
33
34
|
await unlockHiddenContent(token, signer);
|
|
34
35
|
return getTokenContent(token);
|
|
35
36
|
}
|
|
37
|
+
/** Removes the unencrypted hidden content */
|
|
38
|
+
export function lockTokenContent(token) {
|
|
39
|
+
Reflect.deleteProperty(token, TokenContentSymbol);
|
|
40
|
+
Reflect.deleteProperty(token, TokenProofsTotalSymbol);
|
|
41
|
+
lockHiddenContent(token);
|
|
42
|
+
}
|
|
36
43
|
/** Gets the totaled amount of proofs in a token event */
|
|
37
44
|
export function getTokenProofsTotal(token) {
|
|
38
45
|
if (isTokenContentLocked(token))
|
|
@@ -65,3 +72,72 @@ export function dumbTokenSelection(tokens, minAmount, mint) {
|
|
|
65
72
|
}
|
|
66
73
|
return selected;
|
|
67
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns a decoded cashu token inside an unicode emoji
|
|
77
|
+
* @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/ReceiveTokenDialog.vue#L387
|
|
78
|
+
*/
|
|
79
|
+
export function decodeTokenFromEmojiString(str) {
|
|
80
|
+
try {
|
|
81
|
+
let decoded = [];
|
|
82
|
+
const chars = Array.from(str);
|
|
83
|
+
if (!chars.length)
|
|
84
|
+
return undefined;
|
|
85
|
+
const fromVariationSelector = function (char) {
|
|
86
|
+
const codePoint = char.codePointAt(0);
|
|
87
|
+
if (codePoint === undefined)
|
|
88
|
+
return null;
|
|
89
|
+
// Handle Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
|
|
90
|
+
if (codePoint >= 0xfe00 && codePoint <= 0xfe0f) {
|
|
91
|
+
// Maps FE00->0, FE01->1, ..., FE0F->15
|
|
92
|
+
const byteValue = codePoint - 0xfe00;
|
|
93
|
+
return String.fromCharCode(byteValue);
|
|
94
|
+
}
|
|
95
|
+
// Handle Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
|
|
96
|
+
if (codePoint >= 0xe0100 && codePoint <= 0xe01ef) {
|
|
97
|
+
// Maps E0100->16, E0101->17, ..., E01EF->255
|
|
98
|
+
const byteValue = codePoint - 0xe0100 + 16;
|
|
99
|
+
return String.fromCharCode(byteValue);
|
|
100
|
+
}
|
|
101
|
+
// No Variation Selector
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
// Check all input chars for peanut data
|
|
105
|
+
for (const char of chars) {
|
|
106
|
+
let byte = fromVariationSelector(char);
|
|
107
|
+
if (byte === null && decoded.length > 0) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
else if (byte === null) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
decoded.push(byte); // got some
|
|
114
|
+
}
|
|
115
|
+
// Switch out token if we found peanut data
|
|
116
|
+
let decodedString = decoded.join("");
|
|
117
|
+
return getDecodedToken(decodedString);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Encodes a token into an emoji char
|
|
125
|
+
* @see https://github.com/cashubtc/cashu.me/blob/1194a7b9ee2f43305e38304de7bef8839601ff4d/src/components/SendTokenDialog.vue#L710
|
|
126
|
+
*/
|
|
127
|
+
export function encodeTokenToEmoji(token, emoji = "🥜") {
|
|
128
|
+
return (emoji +
|
|
129
|
+
Array.from(typeof token === "string" ? token : getEncodedToken(token))
|
|
130
|
+
.map((char) => {
|
|
131
|
+
const byteValue = char.charCodeAt(0);
|
|
132
|
+
// For byte values 0-15, use Variation Selectors (VS1-VS16): U+FE00 to U+FE0F
|
|
133
|
+
if (byteValue >= 0 && byteValue <= 15) {
|
|
134
|
+
return String.fromCodePoint(0xfe00 + byteValue);
|
|
135
|
+
}
|
|
136
|
+
// For byte values 16-255, use Variation Selectors Supplement (VS17-VS256): U+E0100 to U+E01EF
|
|
137
|
+
if (byteValue >= 16 && byteValue <= 255) {
|
|
138
|
+
return String.fromCodePoint(0xe0100 + (byteValue - 16));
|
|
139
|
+
}
|
|
140
|
+
return "";
|
|
141
|
+
})
|
|
142
|
+
.join(""));
|
|
143
|
+
}
|
package/dist/helpers/wallet.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const WalletMintsSymbol: unique symbol;
|
|
|
8
8
|
export declare function isWalletLocked(wallet: NostrEvent): boolean;
|
|
9
9
|
/** Unlocks a wallet and returns the hidden tags */
|
|
10
10
|
export declare function unlockWallet(wallet: NostrEvent, signer: HiddenContentSigner): Promise<string[][]>;
|
|
11
|
+
export declare function lockWallet(wallet: NostrEvent): void;
|
|
11
12
|
/** Returns the wallets mints */
|
|
12
13
|
export declare function getWalletMints(wallet: NostrEvent): string[];
|
|
13
14
|
/** Returns the wallets private key as a string */
|
package/dist/helpers/wallet.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hexToBytes } from "@noble/hashes/utils";
|
|
2
|
-
import { getHiddenTags, getOrComputeCachedValue, isHiddenTagsLocked, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
2
|
+
import { getHiddenTags, getOrComputeCachedValue, isHiddenTagsLocked, lockHiddenTags, unlockHiddenTags, } from "applesauce-core/helpers";
|
|
3
3
|
export const WALLET_KIND = 17375;
|
|
4
4
|
export const WALLET_BACKUP_KIND = 375;
|
|
5
5
|
export const WalletPrivateKeySymbol = Symbol.for("wallet-private-key");
|
|
@@ -12,6 +12,11 @@ export function isWalletLocked(wallet) {
|
|
|
12
12
|
export async function unlockWallet(wallet, signer) {
|
|
13
13
|
return await unlockHiddenTags(wallet, signer);
|
|
14
14
|
}
|
|
15
|
+
export function lockWallet(wallet) {
|
|
16
|
+
Reflect.deleteProperty(wallet, WalletPrivateKeySymbol);
|
|
17
|
+
Reflect.deleteProperty(wallet, WalletMintsSymbol);
|
|
18
|
+
lockHiddenTags(wallet);
|
|
19
|
+
}
|
|
15
20
|
/** Returns the wallets mints */
|
|
16
21
|
export function getWalletMints(wallet) {
|
|
17
22
|
return getOrComputeCachedValue(wallet, WalletMintsSymbol, () => {
|
|
@@ -6,7 +6,7 @@ import { subscribeSpyTo } from "@hirez_io/observer-spy";
|
|
|
6
6
|
import { FakeUser } from "../../__tests__/fake-user.js";
|
|
7
7
|
import { WalletBlueprint } from "../../blueprints/wallet.js";
|
|
8
8
|
import { WalletQuery } from "../wallet.js";
|
|
9
|
-
import { unlockWallet } from "../../helpers/wallet.js";
|
|
9
|
+
import { lockWallet, unlockWallet } from "../../helpers/wallet.js";
|
|
10
10
|
const user = new FakeUser();
|
|
11
11
|
const factory = new EventFactory({ signer: user });
|
|
12
12
|
let events;
|
|
@@ -18,6 +18,7 @@ beforeEach(() => {
|
|
|
18
18
|
describe("WalletQuery", () => {
|
|
19
19
|
it("it should update when event is unlocked", async () => {
|
|
20
20
|
const wallet = await user.signEvent(await factory.create(WalletBlueprint, generateSecretKey(), []));
|
|
21
|
+
lockWallet(wallet);
|
|
21
22
|
events.add(wallet);
|
|
22
23
|
const spy = subscribeSpyTo(queries.createQuery(WalletQuery, await user.getPublicKey()));
|
|
23
24
|
await unlockWallet(wallet, user);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-wallet",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20250314133024",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -80,16 +80,16 @@
|
|
|
80
80
|
"@cashu/cashu-ts": "2.0.0-rc1",
|
|
81
81
|
"@gandlaf21/bc-ur": "^1.1.12",
|
|
82
82
|
"@noble/hashes": "^1.7.1",
|
|
83
|
-
"applesauce-actions": "0.0.0-next-
|
|
84
|
-
"applesauce-core": "0.0.0-next-
|
|
85
|
-
"applesauce-factory": "0.0.0-next-
|
|
83
|
+
"applesauce-actions": "0.0.0-next-20250314133024",
|
|
84
|
+
"applesauce-core": "0.0.0-next-20250314133024",
|
|
85
|
+
"applesauce-factory": "0.0.0-next-20250314133024",
|
|
86
86
|
"nostr-tools": "^2.10.4",
|
|
87
87
|
"rxjs": "^7.8.1"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
91
91
|
"@types/debug": "^4.1.12",
|
|
92
|
-
"applesauce-signers": "0.0.0-next-
|
|
92
|
+
"applesauce-signers": "0.0.0-next-20250314133024",
|
|
93
93
|
"typescript": "^5.7.3",
|
|
94
94
|
"vitest": "^3.0.5"
|
|
95
95
|
},
|